Windows 下串口通信(上)

作者:小马

 

如果你不想用开发工具自带的串口操作控件,想写一个灵活的串口操作类,下面的内容会对你有用.

一 打开串口
打开串口自然是用CreateFile, 这个倒不难, 关健是几个参数该怎么填. CreateFile有7个参数.
LPCTSTR lpFileName
这个填串口号, 比如你用com1, 传进来”com1”就可以了.这里有一点要注意,如果你的串口号是com1到com9, 按上面说的传参没有问题, 如果 com9以上,比如com10, 就要用下面这样的形式,” \\\\.\\COM10 ”

DWORD dwDesiredAccess
访问方式, 读,写或可读可写, 一般我们用串口,既要发送数据又会接收据, 可以设置为
GENERIC_READ | GENERIC_WRITE.
DWORD dwShareMode
共享模式, 在串口操作中,这个值一般设置为0, 表示不能共享,独占. 这个道理很容易明白,串口是硬件的I/O操作,读写时肯定要独占.
LPSECURITY_ATTRIBUTES lpSecurityAttributes
这个值在串口应用中,一般不必关心,直接置为null.
DWORD dwCreationDisposition
这个表示如果文件存在或不存在时,createfile的动作, 很明显,在串口应用中,OPEN_EXISTING,表示打开已存在的串口. 如果串口不存在,不可能去创建一个吧.
DWORD dwFlagsAndAttributes
文件的属性和标志位, 在串口应用中, 有两种操作模式, 同步(Nonoverlapped)和异步(overlapped), 同步该值为0, 异步模式, 该值可设置为FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED或FILE_FLAG_OVERLAPPED.


下面解释一下同步和异步的概念.
这两个的差异体现在接收和发送数据上, 拿发送数据举个例子, 同步模式下,发送函数返回(可能成功或失败), 操作才完成,否则当前发送线程会阻塞,直到发送完成. 而异步模式通过事件通知来避免阻塞,你可以在发送数据的同时,做其它事情,然后检测事件来判断操作是否完成. 关于同步和异步,在进发送和接收数据时,还有更详细的描述.


HANDLE hTemplateFile
这个值直接置为null.

该函数如果成功,返回一个有效的串口句柄,否则返回INVALID_HANDLE_VALUE, 注意不是FALSE.

 

二 串口参数设置
2.1 波特率,停止位,字节大小,奇偶校验
这几个参数都存在于一个叫DCB的结构体内, 我们只需给这几个变量赋值然后,调用SetCommState就可以了. 这里有一点要注意, 因为DCB结构体中还有其它成员变量, 对于我们不需要改变的,要知道它们原来的值,以免调用SetCommState之后出错. 所以,一般是用如下的方式设置这几个成员.
DCB dcb;
FillMemory(&dcb, sizeof(dcb), 0);//初始化为空
 if (!GetCommState(hComm, &dcb))     // 取当前dcb设置
      // Error in GetCommState
     return FALSE;
// 更新自己要设置的值
   dcb.BaudRate = CBR_9600 ;//波特率,9600
   dcb.Parity = NOPARITY;   //无奇偶校验


   // 更改设置
   if (!SetCommState(hComm, &dcb))
         return false

通过上面方法,就可以避免更改其它的成员.


2.2 超时时间
超时时间包括写超时和读超时,都在COMMTIMEOUTS这个结构体中的成员中。
WriteTotalTimeoutMultiplier和WriteTotalTimeoutConstant有和写操作有关的超时时间.
一次写操作的超时时间为WriteTotalTimeoutMultiplier*(字符数)+WriteTotalTimeoutConstant.
比如要发送10个字节, WriteTotalTimeoutMultiplier = 100, WriteTotalTimeoutConstant = 2000.
那么写操作超超时间为100*10+2000 = 3000ms.


在同步模式下, 如果3000ms内没有发送完数据,WriteFile函数会超时返回,可通过函数返回的实际发送的字节数来判断发送是否完成.
在异步模式下, 情况比较复杂一点, 下面讲到发送数据的时候再详述.


如果WriteTotalTimeoutMultiplier和WriteTotalTimeoutConstant的值都为0,表示写操作无超时时间.
ReadIntervalTimeout, ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant三个变量是和读操作有关的超时时间. 后面两个变量用法与写操作类似. 第一个变量, 表示读数据时,两个字节之间的间隔时间,如果该值为0,表示间隔超时不使用.
如果是下面这样的设置,
CommTimeOuts.ReadIntervalTimeout = MAXWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
读一次缓冲区操作立即返回, 不管读到的是什么,读到多少个字节. 这样的设置还是比较常用的.


超时时间的设置比较灵活, 具体如何设置要根据实际应用, 比如有些应用中,用户在上层自己控制读和写的超时时间, 这种情况下,上面的设置意义就不大.

 

原文 http://ponymaggie.blog.sohu.com/167348968.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值