串口通信

查阅资料,https://blog.csdn.net/songshu5555/article/details/78808039

串口的操作可以有两种操作方式:同步操作方式和重叠操作方式(又称为异步操作方式)。

同步操作时,API函数会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而重叠操作方式,API函数会立即返回,操作在后台进行,避免线程的阻塞。

无论那种操作方式,一般都通过四个步骤来完成:

  • (1) 打开串口
  • (2) 配置串口
  • (3) 读写串口
  • (4) 关闭串口

1、打开串口

Win32系统把文件的概念进行了扩展。无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的。该函数的原型为:

C++代码

HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);

1

HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);

  • lpFileName:将要打开的串口逻辑名,如"COM1";
  • dwDesiredAccess:指定串口访问的类型,可以是读取、写入或二者并列;
  • dwShareMode:指定共享属性,由于串口不能共享,该参数必须置为0;
  • lpSecurityAttributes:引用安全性属性结构,缺省值为NULL;
  • dwCreationDistribution:创建标志,对串口操作该参数必须置为OPEN_EXISTING;
  • dwFlagsAndAttributes:属性描述,用于指定该串口是否进行异步操作,该值为FILE_FLAG_OVERLAPPED,表示使用异步的I/O;该值为0,表示同步I/O操作;
  • hTemplateFile:对串口而言该参数必须置为NULL。

例1:打开串口及初始化配置

串口通信

调用方式类似根据上述接口如下:

串口通信

:针对COM10以上及非COM*的串口号,需在串口名称前加\\\\.\\,是由于windows在定义串口连接时只限制了COM10以下的串口号,波特率必须与设备手册制定的相同,否则会发送命令反馈的数据不对

2配置串口

       一般用CreateFile打开串口后,可以调用GetCommState函数来获取串口的初始配置。要修改串口的配置,应该先修改DCB结构,然后再调用SetCommState函数设置串口。

串口通信

 除了在BCD中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。Windows用I/O缓冲区来暂存串口输入和输出的数据。如果通信的速率较高,则应该设置较大的缓冲区。调用SetupComm函数可以设置串行口的输入和输出缓冲区的大小。

BOOL SetupComm( HANDLE hFile, // 通信设备的句柄

DWORD dwInQueue, // 输入缓冲区的大小(字节数)

DWORD dwOutQueue // 输出缓冲区的大小(字节数) );

在用ReadFile和WriteFile读写串行口时,需要考虑超时问题。超时的作用是在指定的时间内没有读入或发送指定数量的字符,ReadFile或WriteFile的操作仍然会结束。

读写串口的超时有两种:间隔超时和总超时。间隔超时是指在接收时两个字符之间的最大时延。总超时是指读写操作总共花费的最大时间。写操作只支持总超时,而读操作两种超时均支持。用COMMTIMEOUTS结构可以规定读写操作的超时,以毫秒为单位。

COMMTIMEOUTS结构的定义为:

串口通信

在读写串口之前,还要用PurgeComm()函数清空缓冲区。

3、读写串口

①写串口命令

串口通信

②读串口反馈命令

a. 方法1

串口通信

b.方法2

串口通信

//接收串口反馈回的字符串

串口通信

4、关闭串口

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

串口通信