帧头:ACK(06H),长度为1字节。
地址:与接收到的命令中的地址信息相同,长度为1字节。
子地址:与接收到的命令中的地址信息相同,长度为1字节。
其它分析与上同。
4). 正响应帧
帧头 地址 校验和 帧尾
帧头:ACK (06H),长度为1字节。
地址:与接收到的命令中的地址信息相同,长度为1字节。
其它分析与上同。
5). 否定响应帧
帧头 地址 错误码 校验和 帧尾
帧头:NAK (15H),长度为1字节。
地址:与接收到的命令中的地址信息相同,长度为1字节。
错误码:
1 (31H)表示命令不存在;
2 (32H)表示重发命令;
3 (33H)表示设置范围超限;
4 (34H)表示当前状态不能设置(运行于自动调整方式);
5 (35H)表示键控模式。
其它分析与上同。
5.1.2 PC机侧通信程序的实现
在本程序中设计了三个线程,用户界面线程就是程序的主线程,另外再添加两个工作线程:通信线程和延时线程。它们的功能介绍如表5-1所示。
线程名称 主要功能 线程函数
主线程 响应用户对控件的调用(设置控件属性和调用控件方法);初始化串口;处理通信线程接收到的数据,并通知用户(触发控件消息) ;通知通信线程向串口写数据。
通信线程 在主线程初始化串口后被创建。CommThread函数进入死循环,线程将一直监视串口事件,当读串口事件发生时,读取串口接收到的数据,并向主线程发自定义消息WM_COMM_RXCHAR,通知主线程处理数据;当收到主线程的写串口命令时,将缓存中的数据写到串口。
CommThread(LPVOID
pParam)
延时线程 在主线程向串口写数据之后被创建。如果主线程收到了正确的响应,会将全局变量bReceiveSuccess置为真,延时线程在检查到其为真后,线程函数返回;否则会延时10ms再判断一次。如果超过了
规定时间仍没检查到其为真,则向主线程发自定义消息WM_DELAY_TIMEOUT,通知主线程重发刚才的命令,然后线程函数返回。
DelayThread(LPVOID pParam)
5.1.2.1 主要函数介绍
1).串口设备初始化
初始化函数首先获得串口设备句柄,然后对其进行通信参数设置,包抱设置输入/输出缓冲区大小、超时控制和事件监视等。其中用到的函数有:
打开串口函数:
HANDLE CreateFile(
LPCTSTR lpFileName,//被打开的串口名,如“COM1”、“COM2”等
DWORD dwDesiredAccess,//访问模式(读写模式)
DWORD dwSharedMode,//共享模式
DWORD LPSECURITY_ATTRIBUTES lpSecurityAttributes,//安全描述符地址
DWORD dwCreationDistribute,//如何打开文件
DWORD dwFlagsAndAttributes,//文件属性,
HANDLE hTemplateFile//模板文件句柄
);
如果函数调用成功,则返回一个打开的串口句柄,否则返回INVALID_HANDLE_VALUE。
设置串口状态函数
先调用函数BOOL GetCommState(HANDLE hFile,LPDCB lpDCB)获得上面返回的串口句柄的确省dcb结构,修改相关参数后在调用
BOOL SetCommState(HANDLE hFile,LPDCB lpDCB)
函数完成对串口状态的设置。
其中,lpDCB是指向DCB结构的指针。DCB结构的参数项很多,主要包括波特率、数据位数、奇偶检验、停止位的设置等。如果函数调用成功则返回值为TRUE,否则返回值为FALSE。
缓冲区设置函数
可以调用下面的函数重新分配发送和接收缓冲区的大小。
BOOL SetupComm(HANDLE hFile,DWORD dwInQueue,DWORD dwOutQueue);
清除缓冲区函数
BOOL PurgeComm(HANDLE hFile,DWORD dwFlags)
如清除发送缓冲区,则参数dwFlags设置位PURGE_TX_CLEAR;如清除接收缓冲区,则参数dwFlags设为PURGE_RX_CLEAR。
创建监视事件函数
HANDLE CreateEvent(LPSECURITY_ATRRIBUTES lpEventAttributes,//事件的安全属性指针,为NULL时,不能被继承
BOOL bManualReset,//手工重置事件
BOOL bInitialState,//初始化状态,
LPCTSTR lpName);//事件对象的指针
在程序中,创建了三个人工重置、没发信号的事件
线程创建函数
利用函数CWinThread* AfxBeginThread( AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL )来创建线程函数。参数pfnThreadProc为全局函数名,pParam为传递给全