1、打开串口
win32系统把文件的概念进行了扩展。无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用api函数createfile来打开或创建的。该函数的原型为:
handlecreatefile(lpctstrlpfilename,
dworddwdesiredaccess,
dworddwsharemode,
lpsecurity_attributeslpsecurityattributes,
dworddwcreaTIondistribuTIon,
dworddwflagsandattributes,
handlehtemplatefile);
各个参数说明如下:
lpfilename:将要打开的串口逻辑名,如“com1”;
dwdesiredaccess:指定串口访问的类型,可以是读取、写入或二者并列;
dwsharemode:指定共享属性,由于串口不能共享,该参数必须置为0;
lpsecurityattributes:引用安全性属性结构,缺省值为null;
dwcreaTIondistribuTIon:创建标志,对串口 *** 作该参数必须置为open_existing;
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中串行通信是必不可少的技术,所以掌握串行通信的开发方法具有现实意义。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)