C++串口通信

串口编程步骤

                 基于win32API

写在前面:

关于串口通信,网上的文章代码很多,之所以还要写这篇文章主要是因为本人在写串口通信时还是遇到了一些挫折,想借写此文章进一步加深对串口通信的理解,同时也是对这两天的一个总结吧。

这几天项目要求用C++写串口通信,于是果断上网搜关于C++串口通信的代码,还真是一搜一箩筐。由于本人编程能力有限,刚开始看到那些代码时,感觉好麻烦,于是看了两行后不想看了,然后又开始找其他代码。这样烦躁的忙碌了一天后,感觉不对劲。在这样下去这串口通信是没法整明白了,自己估计也得疯掉。醒悟后,开始慢慢平静心情,我先找了一篇关于介绍串口通信一般步骤的文章,认真读完一遍后,感觉收获挺大。鉴于本人较懒,于是我直接又从网上找了几份c++串口通信的代码研究,研究发现,代码主要分两类,一类是利用串口控件,另一类是直接利用Win32API。本文主要讲第二类,主要原因是我的VC++6.0貌似找不到串口控件,郁闷呀。不过利用API编程还是挺有趣的嘛。废话不说了,先来说说串口通信的一些基本函数吧。

1.打开串口。

  所用函数:

HANDLE CreateFIle(LPCTSTR  lpFileName,  

                  DWORD  dwAccess,  

               DWORD  dwShareMode,                           LPSECURITY_ATTRIBUTES lpsa

                  DWORD  dwCreate,

   DWORD  dwAttrsAndFlags,

   HANDLE  hTemplateFile)

参数介绍:

LPCTSTR  lpFileName将要打开的串口逻辑名,如COM1 COM2

DWORD  dwAccess指定串口访问的类型,可以是读取、写入或两者 并列

DWORD  dwShareMode指定共享属性,由于串口不能共享,该参数 必须置为0                    LPSECURITY_ATTRIBUTES lpsa引用安全性属性结构,缺省值NULL

DWORD  dwCreate创建标志,对串口操作该参数必须置为OPEN  EXISTING

DWORD  dwAttrsAndFlags属性描述,用于指定该串口是否可进行 异步操作

HANDLE  hTemplateFile指向模板文件的句柄,对串口而言该参数 必须置为NULL

例如,以下程序用于以同步读写方式打开串口COM1

HANDLE hCom;
DWORD dwError;
hCon = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hCom == (HANDLE)0xFFFFFFFF)
{
 dwError = GetLastError();
 MessageBox(dwError);
}

2.配置串口

配置串口是通过改变设备控制块DCB(Device Control Block) 的成员变量值来实现的,接收缓冲区和发送缓冲区的大小可通过SetupComm函数来设置。

DCB的结构体定义如下:

typedef struct _DCB { // dcb 
 DWORD DCBlength; // sizeof(DCB) 
 DWORD BaudRate; // current baud rate 
 DWORD fBinary: 1; // binary mode, no EOF check 
 DWORD fParity: 1; // enable parity checking 
 DWORD fOutxCtsFlow:1; // CTS output flow control 
 DWORD fOutxDsrFlow:1; // DSR output flow control 
 DWORD fDtrControl:2; // DTR flow control type 
 DWORD fDsrSensitivity:1; // DSR sensitivity 
 DWORD fTXContinueOnXoff:1; // XOFF continues Tx 
 DWORD fOutX: 1; // XON/XOFF out flow control 
 DWORD fInX: 1; // XON/XOFF in flow control 
 DWORD fErrorChar: 1; // enable error replacement 
 DWORD fNull: 1; // enable null stripping 
 DWORD fRtsControl:2; // RTS flow control 
 DWORD fAbortOnError:1; // abort reads/writes on error 
 DWORD fDummy2:17; // reserved 
 WORD wReserved; // not currently used 
 WORD XonLim; // transmit XON threshold 
 WORD XoffLim; // transmit XOFF threshold 
 BYTE ByteSize; // number of bits/byte, 4-8 
 BYTE Parity; // 0-4=no,odd,even,mark,space 
 BYTE StopBits; // 0,1,2 = 1, 1.5, 2 
 char XonChar; // Tx and Rx XON character 
 char XoffChar; // Tx and Rx XOFF character 
 char ErrorChar; // error replacement character 
 char EofChar; // end of input character 
 char EvtChar; // received event character 
 WORD wReserved1; // reserved; do not use 
} DCB; 
SetupComm函数的原型则为:
BOOL SetupComm(
 HANDLE hFile, // handle to communications device
 DWORD dwInQueue, // size of input buffer
 DWORD dwOutQueue // size of output buffer
);

那么长一大串,看都不想看,想要记住谈何容易。其实关于DCB的属性我们一般只需设置下面程序中的几个。

以下程序将串口设置为:波特率为9600,数据位数为7位,停止位为位,偶校验,接收缓冲区和发送缓冲区大小均为1024个字节,最后用PurgeComm函数终止所有的后台读写操作并清空接收缓冲区和发送缓冲区:

DCB dcb;
dcb.BaudRate = 9600; //波特率为9600
dcb.ByteSize = 7; //数据位数为7
dcb.Parity = EVENPARITY; //偶校验
dcb.StopBits = 2; //两个停止位
dcb.fBinary = TRUE;
dcb.fParity = TRUE;
if (!SetCommState(hCom, &dcb))
{
 MessageBox("串口设置出错!");

SetupComm(hCom, 1024, 1024);
PurgeComm(hCom, PURCE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

3读写串口

读串口

对串口进行读取所用的函数和对文件进行读取所用的函数相同,读函数原型如下:

BOOL ReadFile(
 HANDLE hFile, // handle of file to read
 LPVOID lpBuffer, // pointer to buffer that receives data
 DWORD nNumberOfBytesToRead, // number of bytes to read
 LPDWORD lpNumberOfBytesRead, // pointer to number of bytes read
 LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O
);

写串口

对串口进行写入所用的函数和对文件进行写入所用的函数相同,写函数原型如下:

BOOL WriteFile(
 HANDLE hFile, // handle to file to write to
 LPCVOID lpBuffer, // pointer to data to write to file
 DWORD nNumberOfBytesToWrite, // number of bytes to write
 LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written
 LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O
);

4关闭串口
  利用API 函数实现串口通信时关闭串口非常简单,只需使用CreateFile 函数返回的句柄作为参数调用CloseHandle 即可:

BOOL CloseHandle(
 HANDLE hObject // handle to object to close
);

完了,关于串口通信的一般步骤就是这几步了,现在想起来其实还是挺简单的。当然想要深入还是有很东西要学的,不过对于我这个初学者来说,明白这些就已经够用了,更深的东西今后慢慢学吧。

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值