最近同事要再版多年前出版的《单片机教程》,当年帮助编写了与PC机通信一节。
顺手封装了一个类,整理如下:
本例题要求在PC机与单片机间通过串行通信实现从单片机向PC机的数据发送,具体要求是:首先由PC机向单片机发送一个“S”的ASCII码作为联络信号,单片机收到“S”后,发一个“A”的ASCII码作为应答信号。PC机收到“A”后,向单片机发送一个“F”的ASCII码命令信号,单片机收到“F”后,开始从内存50H取数据,并连续发送10个字节的数据,最后发送这10个数据的累加和校验。PC机在收到发送过来的数据和累加和后,与自己的累加和相比较,相同则发一个“J”的ASCII码作为应答信号,表示本次通信结束;不同则发一个“C”的ASCII码作为应答信号,表示本次通信失败,要求重新发送。单片机发送三次之后如果仍然不对,则作错误处理
在软件设计时一定要注意单片机与PC机之间应该遵守相同的通信协议,其主要包括波特率、传输帧格式、校验位等。除此之外,如果要实现PC机与多个单片机的通信,PC机还应该向单片机发送欲寻单片机的地址编码,而单片机中要编写地址识别程序段。
本例题的通信协议约定如下:
波特率:2400b/s;
帧格式:1位起始位,8位数据位,1位停止位,无奇偶校验;
传送方式:PC机采用中断方式接收,单片机也采用中断方式接收;
数据长度:一个字节
校验方式:累加和校验;
握手方式:软件握手
1.PC机的通信软件设计
实现PC机串口通信的软件在此采用VC++6.0语言编程,VC提供了一组系统函数用于支持Window平台下的串口通信,在msdn帮助文档中提供了TTY方式通信的例子,我们以这组通信函数为基础,实现了一个用于串口通信的类CCom,此通信类能够与指定串口关联,向串口发送数据,并且可以检测串口,一旦有数据到来,就会以中断方式将数据读入用户缓冲并向主窗口发送消息,利用它可以方便地编制串口应用程序。
源程序清单如下:
通信类头文件Com.h
#define BUFLEN 1024 //缓冲长度
#define WM_COMM_READ WM_USER+1000 //用户自定义的数据读入消息
class CCom : public CObject
{
public:
BOOL VerifyRbuf(); //校验和检查
void dowithRbuf(); //通信协议应答
void Write(char cmd); //发送命令字
void WriteFormat(char * sbuf,BYTE length); //打包发送数据
void Close(); //关闭串口
void Read(); //从串口读数据
void Open(UINT com); //打开串口
HANDLE m_hCom; //串口句柄
CWinThread * m_hThread; //线程句柄
BOOL m_bRun; //是否运行标志
UINT m_com; //串口编号
char m_rbuf[BUFLEN]; //输入缓冲
int m_rbuflen; //输入数据长度
char m_sbuf[BUFLEN]; //输出缓冲
DWORD dwLength; //实际读入(发送)的数据长度
OVERLAPPED osWrite, osRead; //读写操作结果
CCom(); //构造函数
virtual ~CCom(); //析构函数
};
通信类实现Com.cpp
UINT CommWatchProc(VOID* pcom);
CCom::CCom()
{