1.前言
既然有了MSComm这种简单粗暴的控件,为什么还需要CSerialPort类?这是因为与前者相比,这个类在程序的发布上不需要加入其他的文件,而且CSerialPort提供给我们的函数都是开放透明的,允许我们进行二次改造。
CSerialPort类是一个非常好用的多线程串口编程工具,可以在很短的时间就可以完成一个串口通讯框架的搭建,所以有必要加以记载!
2.CSerialPort类的功能及成员函数介绍
2.1 CSerialPort工作流程
首先设置好串口参数,在开启串口监测工作线程,串口监测工作线程监测到串口接收到的数据、流控制事件或其他串口时间后,就以消息的方式通知主程序,激发消息处理函数来进行数据处理,这是对接收数据而言的!发送数据的话,可以直接向串口发送。
2.2 CSerialPort类定义的消息
消息名称 |
消息号 |
功能说明 |
WM_COMM_BREAK_DETECTED |
WM_USER+1 |
检测到输入中断 |
WM_COMM_CTS_DETECTED |
WM_USER+2 |
检测到CTS(清除发送)信号状态改变 |
WM_COMM_DSR_DETECTED |
WM_USER+3 |
检测到DSR(数据准备就绪)状态改变 |
WM_COMM_ERR_DETECTED |
WM_USER+4 |
发生线状态错误(包括CE_FRAME ,CE_OVERRUN,和CE_RXPARITY) |
WM_COMM_RING_DETECTED |
WM_USER+5 |
检测到响铃指示信号 |
WM_COMM_RLSD_DETECTED |
WM_USER+6 |
检测到RLSD(接收线信号)状态改变 |
WM_COMM_RXCHAR |
WM_USER+7 |
接收到一个字符并已放入接受缓冲区 |
WM_COMM_RXFLAG_DETECTED |
WM_USER+8 |
检测到接受到字符(已放缓冲区)事件 |
WM_COMM_TXEMPTY_DETECTED |
WM_USER+9 |
检测到发送缓冲区最后一字符已被发送 |
2.3 CSerialPort类定义的成员函数
1.串口初始化函数InitPort
BOOL CSerialPort::InitPort(CWnd *pPortOwner, // the owner (CWnd) of the port (receives message)
UINT portnr, // portnumber (1..4)
UINT baud, // baudrate
char parity, // parity
UINT databits, // databits
UINT stopbits, // stopbits
DWORD dwCommEvents, // EV_RXCHAR, EV_CTS etc
UINT writebuffersize) // size to the writebuffer
这个函数是用来初始化串口的,即设置串口的通信参数:需要打开的串口号、波特率、奇偶校验方式、数据位、停止位,这里还可 以用来进行事件的设定。
如果串口初始化成功,就返回TRUE,若串口被其他设备占用、不存在或存在其他股占,就返回FALSE,编程者可以在这儿提示串口操作是否成功。
如果在当前主串口调用这个函数,那么pPortOwner可用this指针表示,串口号在函数中做了限制,只能用1,2,3和4四个串口号,而事实上在编程时可能用到更多串口号,可以通过通过注释掉本函数中的“assert(portur>0&&portnr<5)”语句取消对串口号的限制。
2.启用串口通信检测线程函数StartMonitoring()
BOOL CSerialPort::StartMonitoring()
{
if (!(m_Thread = AfxBeginThread(CommThread, this)))
return FALSE;
TRACE("Thread started\n");
return TRUE;
}
串口初始化成功后,就可以调用