异步重叠操作之串口
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
异步重叠操作之串口
在工控行业,目前总线型通信依然占据半壁江山。常用的如485,CAN等。而面对小型系统时,尤其监控区域遍布在两公里范围内时,通过485-232或者CAN-232转换模块,使用上位机的串口与下属硬件通信组成系统便成了相对节约的一种设计方案。
本文的重点在于讲解异步重叠操作串口的思想以及过程。
所有的IO设备的操作都遵循:创建、读写、关闭三个步骤。
第一步:设计类的成员,其中成员此处不详细讲解,之后方法中用到时再谈
View Code
第二步:创建串口通道,在WINDOWS下,一切都表现得那么像文件操作
m_hPort = CreateFile((LPCWSTR)Device, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
其中CreateFile为API函数,其细节如下:
// 作用: CreateFile函数可用来打开或创建文件和端口,它返回该设备的句柄
// 原型:
// HANDLE CreateFile(
// LPCTSTR lpFileName, // 指向文件名的指针
// DWORD dwDesiredAccess, // 访问模式
(GENERIC_WRITE/GENERIC_READ)。0表示仅允许获得与一个设备有关的信息
// DWORD dwShareMode, // 共享模式
(FILE_SHARE_READ/FILE_SHARE_WRITE)。0表述独占
// LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 指向安全属性的指
针
// DWORD dwCreationDisposition, // 创建属
性 CREATE_NEW 创建如果已经存在则冲突
// CREATE_ALWAYS 总是创建,存在则改写
// OPEN_EXISTING 打开现有,由设备提出要求
// OPEN_ALWAYS 打开,不存在则创建
// TRUNCATE_EXISTING 将现有文件缩短为0长度
// DWORD dwFlagsAndAttributes, // 文件属
性 FILE_ATTRIBUTE_ARCHIVE 标记归档属性
// FILE_ATTRIBUTE_COMPRES SED 将文件标记为已压缩,或者标记为文件在目录中的默认压缩方式
// FILE_ATTRIBUTE_NORMA L 默认属性
// FILE_ATTRIBUTE_HIDDE N 隐藏文件或目录
// FILE_ATTRIBUTE_READO NLY 文件为只读
// FILE_ATTRIBUTE_SYSTE M 文件为系统文件
// FILE_FLAG_WRITE_THRO UGH 操作系统不得推迟对文件的写操作
// FILE_FLAG_OVERLAPPED 允许对文件进行重叠操作
// FILE_FLAG_NO_BUFFERIN G 禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块
// FILE_FLAG_RANDOM_AC CESS 针对随机访问对文件缓冲进行优化
// FILE_FLAG_SEQUENTIAL_ SCAN 针对连续访问对文件缓冲进行优化
// FILE_FLAG_DELETE_ON_ CLOSE 关闭了上一次打开的句柄后,将文件删除
// HANDLE hTemplateFile // 用于复制文件句柄,文件模板。如果不为零,则新文件将从这个文件中复制扩展属性
// );
// 返回:
// HANDLE 句柄 INVALID_HANDLE_VALUE 表示出错
此处因为使用异步重叠,所以dwFlagsAndAttributes赋值为
FILE_FLAG_OVERLAPPED。其中Device为设备名称,串口的话直接就是串口号
CHAR Device[80];
sprintf(Device, "COM%d", Port);
第三步:设置串口相关参数:
GetCommState(m_hPort, &dcb); // 读取当前端口的DCB设置
dcb.BaudRate = CBR_9600;
dcb.ByteSize = SERIALPORT_DATABITS_EIGHT; // 库中的选择结
果是5-8,表示5-8位长
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT; // 该参数如果开放,则设置不成功
SetCommState(m_hPort, &dcb); // 设置当前端口的DCB设置
//typedef struct _COMMTIMEOUTS {
// DWORD ReadIntervalTimeout; // 读间隔超时
// DWORD ReadTotalTimeoutMultiplier; // 读时间系数
// DWORD ReadTotalTimeoutConstant; // 读时间常量
// DWORD WriteTotalTimeoutMultiplier; // 写时间系数
// DWORD WriteTotalTimeoutConstant; // 写时间常量
// } COMMTIMEOUTS,*LPCOMMTIMEOUTS;
COMMTIMEOUTS comTimeouts;
GetCommTimeouts(m_hPort, &comTimeouts);
comTimeouts.ReadIntervalTimeout = MAXDWORD;
comTimeouts.ReadTotalTimeoutMultiplier = MAXDWORD; comTimeouts.ReadTotalTimeoutConstant = SERIALPORT_READ_TIMEOUT; comTimeouts.WriteTotalTimeoutMultiplier = MAXDWORD;
comTimeouts.WriteTotalTimeoutConstant = SERIALPORT_WRITE_TIMEOUT;
// 指定一组事件监控通信设备
// 原
型 BOOL WINAPI SetCommMask(__in HANDLE hFile, __in DWORD dwEvtMas k);
// 参数:
// __in HANDLE hFile 通信设备句柄
// __in DWORD dwEvtMask 可以触发的事件
// EV_BREAK 输入中断
// EV_CTS CTS清除发送信号改变