使用Win32API实现Windows下异步串口通讯
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
使用Win32API实现Windows下异步串口通讯
目录
1.异步非阻塞串口通讯的优点
2.异步非阻塞串口通讯的基本原理
3.异步非阻塞串口通讯的基础知识
4.异步非阻塞串口通讯的实现步骤
一、异步非阻塞串口通讯的优点
读写串行口时,既可以同步执行,也可以重叠(异步)执行。
在同步执行时,函数直到操作完成后才返回。这意味着在同步执行时线程会被阻塞,从而导致效率下降。在重叠执行时,即使操作还未完成,调用的函数也会立即返回。费时的I/O操作在后台进行,这样线程就可以干别的事情。
例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。"重叠(overlapped)"一词的含义就在于此。
二,异步非阻塞串口通讯的基本原理
首先,确定要打开的串口名、波特率、奇偶校验方式、数据位、停止位,传递给CreateFile()函数打开特定串口;
其次,为了保护系统对串口的初始设置,调用GetCommTimeouts()得到串口的原始超时设置;然后,初始化DCB对象,调用SetCommState() 设置DCB,调用SetCommTimeouts()设置串口超时控制;
再次,调用SetupComm()设置串口接收发送数据的缓冲区大小,串口的设置就基本完成,之后就可以启动读写线程了。
三,异步非阻塞串口通讯的基础知识
下面来介绍并举例说明一下编写异步非阻塞串口通讯的程序中将会使用到的几个关键函数CreateFile()
功能:打开串口设备
函数原型
HANDLE CreateFile(
LPCTSTR lpFileName, // 串口名称字符串;如:"COM1" 或"COM2"
DWORD dwDesiredAccess, // 设置读写属性(访问模式);一般为GENERIC_READ|GENERIC_WRITE,
DWORD dwShareMode, // 共享模式;"必须"为0, 即不能共享
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全属性;一般为NULL
DWORD dwCreationDistribution, // 创建方式,串口设置必须设置此值;在这里"必须"为OPEN_EXISTING
DWORD dwFlagsAndAttributes, // 文件属性和标志;在这里我们设置成FILE_FLAG_OVERLAPPED ,实现异步I/O
HANDLE hTemplateFile // 临时文件的句柄,通常为NULL
);
说明:
如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。
Forexample:Handlem_hComm = CreateFile(com1,GENERIC_READ||GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAP PED,0);
CloseHandle();
功能:关闭串口
BOOL CloseHandle(
HANDLE hObject // handle to object to close
)
GetCommState()
功能:获得串口状态
BOOL GetCommState(
HANDLE hFile, // handle of communications device
LPDCB lpDCB // address of device-control block structure
);
SetCommState()
功能:设置串口状态
BOOL SetCommState(
HANDLE hFile, // handle of communications device
LPDCB lpDCB // address of device-control block structure
);
说明:
在打开通信设备句柄后,常常需要对串行口进行一些初始化工作。这需要通过一个DCB结构来进行。DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。在查询或配置置串行口的属性时,都要用DCB结构来作为缓冲区。
调用GetCommState函数可以获得串口的配置,该函数把当前配置填充到一个DCB结构中。一般在用CreateFile打开串行口后,可以调用GetCommState函数来获取串行口的初始配置。要修改串行口的配置,应该先修改DCB结构,然后再调用SetCommState函数用指定的DCB 结构来设置串行口
Forexample:
DCB dcb;
memset(&dec,0,dizeof(dcb));
if(!GetCommState(HComm,&dcb))//获取当前DCB配置
return FALSE;
dcb.BaudRate = CBR_9600;//修改数据传输率
............
if(SetCommState(hComm,&dcb))//设置新参数
......//错误处理
BuildCommDCB()
功能:初始化DCB结构
BOOL BuildCommDCB(
LPCTSTR lpDef, // pointer to device-control string
LPDCB lpDCB // pointer to device-control block
);
Forexample:
DCB dcb;
memset(&dcb,0,sizeof(dcb));