如何利用api函数实现串口通信

接口/总线/驱动

51人已加入

描述

  1、打开串口

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

  handlecreatefile(lpctstrlpfilename,

  dworddwdesiredaccess,

  dworddwsharemode,

  lpsecurity_attributeslpsecurityattributes,

  dworddwcreationdistribution,

  dworddwflagsandattributes,

  handlehtemplatefile);

  各个参数说明如下:

  lpfilename:将要打开的串口逻辑名,如“com1”;

  dwdesiredaccess:指定串口访问的类型,可以是读取、写入或二者并列;

  dwsharemode:指定共享属性,由于串口不能共享,该参数必须置为0;

  lpsecurityattributes:引用安全性属性结构,缺省值为null;

  dwcreationdistribution:创建标志,对串口操作该参数必须置为open_existing;

  dwflagsandattributes:属性描述,用于指定该串口是否进行异步操作,该值为file_flag_overlapped,表示使用异步的i/o;该值为0,表示同步i/o操作;

  htemplatefile:对串口而言该参数必须置为null;

  2、配置串口

  在打开通讯设备句柄后,常常需要对串口进行一些初始化配置工作。这需要通过一个dcb结构来进行。dcb结构包含了诸如波特率、数据位数、奇偶校验和停止位数等信息。在查询或配置串口的属性时,都要用dcb结构来作为缓冲区。在打开串口后,可以调用getcommstate函数来获取串口的默认配置,该函数获取一个dcb结构体,只要在该结构内对应该先修改dcb结构,然后再调用setcommstate函数以修改后的dcb结构设置串口。dcb主要有以下几个重要的成员:bytebytesize;//通信字节位数byteparity;//指定奇偶校验方法。此成员可以有下列值://evenparity偶校验noparity无校验//markparity标记校验oddparity奇校验bytestopbits;//指定停止位的位数。此成员可以有下列值://onestopbit1位停止位//twostopbits2位停止位//one5stopbits1.5位停止位

  除了使用bcd设置串口的一些基本参数外,一般还需要设置串口收发数据缓冲区的大小和超时,超时的作用是在指定的时间内没有读入或发送指定数量的字符,读写操作仍然会结束。windows用i/o缓冲区来暂存串口输入和输出的数据,如果通信的速率较高,则应该设置较大的缓冲区。我们可以使用api函数setupcomm设置串口的输入和输出缓冲区的大小,其原型如下:boolsetupcomm(handlehfile,//串口句柄dworddwinqueue,//输入缓冲区的大小(字节数)dworddwoutqueue);//输出缓冲区的大小(字节数)

  关于读写串口的超时设置,windows给我们提供一个专门的结构体commtimeouts,其定义如下:typedefstruct_commtimeouts{dwordreadintervaltimeout;//读间隔超时dwordreadtotaltimeoutmultiplier;//读时间系数dwordreadtotaltimeoutconstant;//读时间常量dwordwritetotaltimeoutmultiplier;//写时间系数dwordwritetotaltimeoutconstant;//写时间常量}commtimeouts,*lpcommtimeouts;

  commtimeouts结构的成员都以毫秒为单位。总超时的计算公式是:

  总超时=时间系数×要求读/写的字符数+时间常量

  例如,要读入10个字符,那么读操作的总超时的计算公式为:

  读总超时=readtotaltimeoutmultiplier×10+readtotaltimeoutconstant

  通过该结构体windowsapi为我们提供两个函数:getcommtimeouts和setcommtimeouts,前者获取当前的超时设置,后者使用修改后的commtimeouts设置超时,与设置串口阐述类似。

  在读写串口之前,还要用purgecomm(…)函数清空缓冲区,该函数原型:

  boolpurgecomm(

  handlehfile,//串口句柄

  dworddwflags);//需要完成的操作

  参数dwflags指定要完成的操作,可以是下列值的组合:

  purge_txabort中断所有写操作并立即返回,即使写操作还没有完成。

  purge_rxabort中断所有读操作并立即返回,即使读操作还没有完成。

  purge_txclear清除输出缓冲区

  purge_rxclear清除输入缓冲区

  3、读写串口

  读写串口使用readfile和writefile两个函数,其原型如下:boolreadfile(handlehfile,//串口的句柄lpvoidlpbuffer,//保存读入数据的指针,dwordnnumberofbytestoread,//要读入的数据的字节数lpdwordlpnumberofbytesread,//实际读入的字节数lpoverlappedlpoverlapped);//overlapped,同步为null

  boolwritefile(

  handlehfile,//串口的句柄

  lpcvoidlpbuffer,//要写入数据的地址

  dwordnnumberofbytestowrite,//要写入数据的字节数

  lpdwordlpnumberofbyteswritten,//实际写入的字节数

  lpoverlappedlpoverlapped);//overlapped,同步为null在进行同步操作时,读写函数要等到执行完才返回,而在异步操作时函数立即返回,但不保证读写操作完成,这时候就需要使用overlapped结构进行异步控制,该结构体有一个重要的成员hevent,该成员是windows事件对象的句柄在控制线程同步及异步操作时常用到,如果是异步操作,我们可以使用createevent(…)创建事件对象并将返回值赋给hevent,然后使用waitforsingleobject或getoverlappedresult等待读写操作完成,进而达到控制异步操作的目的。3.4关闭串口在不使用串口的时候应该将其关闭,以释放windows的资源供其他程序使用,关闭串口只需调用closehandle(hcomm/*串口句柄*/)即可。4串行通信在世纪星组态软件中的应用作为通用的组态软件,世纪星要与其他plc、智能仪表等设备进行通信,串行通信是主要的方式之一,基于前面所述使用api进行串行通信开发的优点,并考虑程序开发的便捷和可重用等,在世纪星中,我们将串行通信api进行封装,以类的方式对串口进行操作,其中打开串口及配置串口参数的操作我们通过可视化窗口进行设定,然后在封装类中实现,相关的操作处理读写数据外基本都已实现,因为不同的设备有不同的协议,因而读写串口的操作在驱动程序中完成,这样我们的开发人员就不必关注太多其他的相关操作,只需根据实际设备重写读写串口的成员函数即可。5结论windows是当前应用程序开发的主流平台,vc++6.0是该平台强大的开发工具,使用windowsapi开发串口通信的程序可是使我们更加清晰的了解串口通信的机制,并且开发人员可以根据需要使用api进行灵活的程序设计,在scada中串行通信是必不可少的技术,所以掌握串行通信的开发方法具有现实意义。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分