1、打开串口:
HANDLE CreateFile(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
在Windows CE下,利用CreateFile函数打开一个COM口时,dwShareMode(共享模式)必须设置为0,表示独占方式;lpSecurityAttributes(安全参数)必须设置为NULL;hTemplateFile(模板文件)必须设置为NULL;dwCreationDisposition需要设置为OPEN_EXISTING。则上述函数简化为:
HANDLE CreateFile(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
0,
NULL,
OPEN_EXISTING,
DWORD dwFlagsAndAttributes,
NULL
);
其中dwDesiredAccess设置为GENERIC_READ表示可读,设置为GENERIC_WRITE表示可写。通常可通过如下示例打开一个串口。
CreateFile(
_T("COM1:"),
GENERIC_READ | GENERIC_WRITE, //允许读和写
0, //独占方式(共享模式)
NULL,
OPEN_EXISTING, //打开而不是创建(创建方式)
0,
NULL
);
打开串口成功,函数返回串口句柄;打开串口失败,函数返回INVALID_HANDLE_VALUE
2.关闭串口:
BOOL CloseHandle(
HANDLE hObject
);
如:CloseHandle(m_hComm); //m_hComm是CreateFile函数返回的串口句柄。
关闭串口成功,函数返回非零值;关闭串口失败,函数返回零。
DCB结构完全描述了串口的使用参数。
typedef struct _DC{
/*
具体内容见:http://blog.chinaunix.net/uid-23260031-id-2466195.html
*/
}DCB,*LPDCB;
·配置串口:
BOOL GetCommState(
HANDLE hFile,
LPDCB lpDCB
);
该函数用来获取已打开串口的参数信息,并将这些信息填充到lpDCB参数所指向的DCB(设备控制块)中。
返回值:成功返回非零值,失败返回零
BOOL SetCommState(
HANDLE hFile,
LPDCB lpDCB
);
返回值:成功返回非零值,失败返回零
该函数用来设置已打开串口的参数信息。
在设置串口参数时,一般先调用GetCommState函数获取串口参数信息到一个DCB(设备控制块)中,然后对感兴趣的参数进行修改,最后再调用SetCommState函数完成串口参数的配置。
例如可以通过如下代码配置串口参数:
——————————————————————————————————
//得到打开串口的当前属性参数,修改后再重新设置串口。
if (!GetCommState(m_hComm,&DCB_COM1))
{
TRACE(_T("GetCommState error"));
return FALSE;
}
//设置串口参数
DCB_COM1.BaudRate = CBR_9600; // 设置波特率9600
DCB_COM1.fBinary = TRUE; // 设置二进制模式,此处必须设置TRUE
DCB_COM1.fParity = TRUE; // 支持奇偶校验
DCB_COM1.fOutxCtsFlow = FALSE; // No CTS output flow control
DCB_COM1.fOutxDsrFlow = FALSE; // No DSR output flow control
DCB_COM1.fDtrControl = DTR_CONTROL_DISABLE; // No DTR flow control
DCB_COM1.fDsrSensitivity = FALSE; // DSR sensitivity
DCB_COM1.fTXContinueOnXoff = TRUE; // XOFF continues Tx
DCB_COM1.fOutX = FALSE; // No XON/XOFF out flow control
DCB_COM1.fInX = FALSE; // No XON/XOFF in flow control
DCB_COM1.fErrorChar = FALSE; // Disable error replacement
DCB_COM1.fNull = FALSE; // Disable null stripping
DCB_COM1.fRtsControl = RTS_CONTROL_DISABLE; //No RTS flow control
DCB_COM1.fAbortOnError = FALSE; // 当串口发生错误,并不终止串口读写
DCB_COM1.ByteSize = 8; // 数据位,范围:4-8
DCB_COM1.Parity = NOPARITY; // 校验模式
DCB_COM1.StopBits = 0; // 1位停止位
//设置串口参数
if (!SetCommState(m_hComm, &DCB_COM1))
{
TRACE(_T("SetCommState error"));
return FALSE;
}
--------------------------------------------
·读写串口:
BOOL ReadFile(
HANDLE hFile,//CreateFile函数返回的串口句柄
LPVOID lpBuffer,//指定接收数据的缓冲区
DWORD nNumberOfBytesToRead,//想要读取的字节数
LPDWORD lpNumberOfBytesRead,//实际读取的字节数
LPOVERLAPPED lpOverlapped//Windows CE不支持,设置
//为NULL
);
BOOL WriteFile(
HANDLE hFile,//CreateFile函数返回的串口句柄
LPCVOID lpBuffer,//指定存储发送数据的缓冲区
DWORD nNumberOfBytesToWrite,//想要发送的字节数
LPDWORD lpNumberOfBytesWritten,//实际发送的字节数
LPOVERLAPPED lpOverlapped////Windows CE不支持,设置
//为NULL
);
读写函数的返回值都是成功时返回非零值,失败时返回零。
例:
DWORD dwLength;
char *recvBuf = new char[1024];
BOOL fReadState = ReadFile(m_hComm, recvBuf, 1024, &dwLength, NULL);
delete[] recvBuf;
DWORD dwactlen;
char *psendbuf = new char[32];
BOOL fWriteState = WriteFile(m_hComm, psendbuf, 32, &dwactlen, NULL);
delete[] psendbuf;
需要注意的是,由于从串口读写数据的速度比较慢,因此一般情况下,不会在主线程中读写大量的数据,而是创建单独的线程来读写数据,特别是读数据
==================================================
异步串口I/O:
BOOL GetCommMask(
HANDLE hFile,
LPDWORD lpEvtMask
);
BOOL SetCommMask(
HANDLE hFile,
DWORD dwEvtMask
);
BOOL WaitCommEvent(
HANDLE hFile,
LPDWORD lpEvtMask,
LPOVERLAPPED lpOverlapped
);
GetCommMask函数用于得到串口已经设置了的串口事件,参数hFile指定已打开的串口句柄,参数lpEvtMask用于存取得到的串口事件集。SetCommMask函数的功能与GetCommMask函数正好相反,用于设置串口事件集。WaitCommEvent函数用于等待预先设置的串口事件中的某一个事件发生,该函数将阻塞线程,直到预先设置的串口事件中的某一事件的发生。参数lpEvtMask用于存储已经发生的事件,参数lpOverlapped必须设置为NULL,因为在Windows CE中不支持重叠I/O操作。
-----------------------------------------------------
·设置端口读写超时:(不使用这个逾时功能,ReadFile直到所有字符接收完才会返回)
BOOL GetCommTimeouts(
HANDLE hFile,
LPCOMMTIMEOUTS lpCommTimeouts
);
BOOL SetCommTimeouts(
HANDLE hFile,
LPCOMMTIMEOUTS lpCommTimeouts
);
在用ReadFile和WriteFile读写串口时,需要考虑超时问题。如果在指定的时间内没有读出或者写入指定数量的字节数据,那么ReadFile函数或者WriteFile函数就会返回。GetCommTimeouts函数用来查询当前的超时时间设置,该函数会填充一个COMMTIMEOUTS结构。SetCommTimeouts函数用来通过一个COMMTIMEOUTS结构设置超时时间。两个函数的返回值都是成功时返回非零值,失败时返回零。
实例分析:
ReadTotalTimeoutMultiplier:读时间系数。以毫秒为单位设置一个用来计算读操作总超时时间的时间系数。
ReadTotalTimeoutConstant:读时间常量。以毫秒为单位设置一个用来计算读操作总超时时间的时间常量。
读总超时时间 = 读时间系数*要读的字节数 + 读时间常量
WriteTotalTimeoutMultiplier:写时间系数。以毫秒为单位设置一个用来计算写操作总超时时间的时间系数。
WriteTotalTimeoutConstant:写时间常量。以毫秒为单位设置一个用来计算写操作总超时时间的时间常量。
写总超时时间 = 写时间系数*要写的字节数 + 写时间常量
·设置接收/发送缓冲区大小:
BOOL SetupComm(
HANDLE hFile,
DWORD dwInQueue,
DWORD dwOutQueue
);
hFile指定已打开的串口句柄,dwInQueue指定接收缓冲区的大小,dwOutQueue指定发送缓冲区的大小。
返回值:成功时返回非零值,失败时返回零。
例:
SetupComm(m_hComm,512,512);
如果不使用该函数,系统会推荐一个适合的默认值。