异步打开串口的方法文档格式.docx
- 文档编号:22482524
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:23
- 大小:25.62KB
异步打开串口的方法文档格式.docx
《异步打开串口的方法文档格式.docx》由会员分享,可在线阅读,更多相关《异步打开串口的方法文档格式.docx(23页珍藏版)》请在冰豆网上搜索。
COM2"
3DWORDdwDesiredAccess,//设置读写属性(访问模式);
一般为GENERIC_READ|GENERIC_WRITE,
4DWORDdwShareMode,//共享模式;
必须"
为0,即不能共享
5LPSECURITY_ATTRIBUTESlpSecurityAttributes,//安全属性;
一般为NULL
6DWORDdwCreationDistribution,//创建方式,串口设置必须设置此值;
在这里"
为OPEN_EXISTING
7DWORDdwFlagsAndAttributes,//文件属性和标志;
在这里我们设置成FILE_FLAG_OVERLAPPED,实现异步I/O
8HANDLEhTemplateFile//临时文件的句柄,通常为NULL
9);
函数说明:
如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。
例子:
10Handlem_hComm=CreateFile(com1,GENERIC_READ||GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
CloseHandle();
关闭串口
函数原型:
11BOOLCloseHandle(
12HANDLEhObject//handletoobjecttoclose
13)
使用比较简单,其中参数hObject为需要关闭的串口句柄。
GetCommState()
获得串口状态
14BOOLGetCommState(
15HANDLEhFile,//handleofcommunicationsdevice
16LPDCBlpDCB//addressofdevice-controlblockstructure
17);
SetCommState()
设置串口状态
18BOOLSetCommState(
19HANDLEhFile,//handleofcommunicationsdevice
20LPDCBlpDCB//addressofdevice-controlblockstructure
21);
在打开通信设备句柄后,常常需要对串行口进行一些初始化工作。
这需要通过一个DCB结构来进行。
DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。
在查询或配置置串行口的属性时,都要用DCB结构来作为缓冲区。
调用GetCommState函数可以获得串口的配置,该函数把当前配置填充到一个DCB结构中。
一般在用CreateFile打开串行口后,可以调用GetCommState函数来获取串行口的初始配置。
要修改串行口的配置,应该先修改DCB结构,然后再调用SetCommState函数用指定的DCB结构来设置串行口。
举例:
22DCBdcb;
23memset(&
dec,0,dizeof(dcb));
24if(!
GetCommState(HComm,&
dcb))//获取当前DCB配置
25returnFALSE;
26dcb.BaudRate=CBR_9600;
//修改数据传输率
27............
28if(SetCommState(hComm,&
dcb))//设置新参数
29......//错误处理
BuildCommDCB()
初始化DCB结构
30BOOLBuildCommDCB(
31LPCTSTRlpDef,//pointertodevice-controlstring
32LPDCBlpDCB//pointertodevice-controlblock
33);
示例:
34DCBdcb;
35memset(&
dcb,0,sizeof(dcb));
36dcb.DCBlength=sizeof(dcb);
37if(!
BuildCommDCb("
9600,n,8,1"
&
dcb))//"
baud=9600parity=Ndata=8stop=1"
38{
39......//参数修改错误
40returnFALSE;
41}
42else
43{
44......//己准备就绪
45}
SetupComm()
设置I/O缓冲区的大小
46BOOLSetupComm(
47HANDLEhFile,//handletocommunicationsdevice
48DWORDdwInQueue,//sizeofinputbuffer
49DWORDdwOutQueue//sizeofoutputbuffer
50);
说明:
除了在DCB中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。
Windows用I/O缓冲区来暂存串行口输入和输出的数据,如果通信的速率较高,则应该设置较大的缓冲区。
调用SetupComm函数可以设置串行口的输入和输出缓冲区的大小。
先介绍一个结构:
COMMTIMEOUTS
51typedefstruct_COMMTIMEOUTS{
52DWORDReadIntervalTimeout;
//读间隔超时
53DWORDReadTotalTimeoutMultiplier;
//读时间系数
54DWORDReadTotalTimeoutConstant;
//读时间常量
55DWORDWriteTotalTimeoutMultiplier;
//写时间系数
56DWORDWriteTotalTimeoutConstant;
//写时间常量
57}COMMTIMEOUTS,*LPCOMMTIMEOUTS;
再介绍两个函数
GetCommTimeouts
读取TimeOut的值
58BOOLGetCommTimeouts(
59HANDLEhFile,//handleofcommunicationsdevice
60LPCOMMTIMEOUTSlpCommTimeouts//addressofcomm.time-outsstructure
61);
SetCommTimeouts
设置TimeOUt的值
62BOOLSetCommTimeouts(
63HANDLEhFile,//handleofcommunicationsdevice
64LPCOMMTIMEOUTSlpCommTimeouts//addressofcommunicationstime-outstructure
65);
这里顺便介绍一下TimeOut机制的两个性质:
超时函数
在用ReadFile和WriteFile读写串行口时,需要考虑超时问题。
如果在指定的时间内没有读出或写入指定数量的字符,那么ReadFile或WriteFile的操作就会结束。
要查询当前的超时设置应调用GetCommTimeouts函数,该函数会填充一个COMMTIMEOUTS结构。
调用SetCommTimeouts可以用某一个COMMTIMEOUTS结构的内容来设置超时。
有两种超时:
间隔超时和总超时。
间隔超时是指在接收时两个字符之间的最大时延,总超时是指读写操作总共花费的最大时间。
写操作只支持总超时,而读操作两种超时均支持。
用COMMTIMEOUTS结构可以规定读/写操作的超时,该结构的定义为:
COMMTIMEOUTS结构的成员都以毫秒为单位。
总超时的计算公式是:
总超时=时间系数×
要求读/写的字符数+时间常量
例如,如果要读入10个字符,那么读操作的总超时的计算公式为:
读总超时=ReadTotalTimeoutMultiplier×
10+ReadTotalTimeoutConstant
可以看出,间隔超时和总超时的设置是不相关的,这可以方便通信程序灵活地设置各种超时。
如果所有写超时参数均为0,那么就不使用写超时。
如果ReadIntervalTimeout为0,那么就不使用读间隔超时,如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都为0,则不使用读总超时。
如果读间隔超时被设置成MAXDWORD并且两个读总超时为0,那么在读一次输入缓冲区中的内容后读操作就立即完成,而不管是否读入了要求的字符。
在用重叠方式读写串行口时,虽然ReadFile和WriteFile在完成操作以前就可能返回,但超时仍然是起作用的。
在这种情况下,超时规定的是操作的完成时间,而不是ReadFile和WriteFile的返回时间。
66COMMTIMEOUTStimeOver;
67memset(&
&
timeOver.0.sizeof(timeOver));
68DWORDtimeMultiplier,timeConstant;
69timeOver.ReadTotalTimeoutMultiplier=timeMultiplier;
70timeOver.ReadTotalTimeoutConstant=timeConstant;
71SetCommTimeouts(hComport,&
timeOver);
ReadFile()
读取数据
72BOOLReadFile(
73HANDLEhFile,//串口名称字符串(文件句柄)
74LPVOIDlpBuffer,//读缓冲区
75DWORDnNumberOfBytesToRead,//要求读入的字节数
76LPDWORDlpNumberOfBytesRead,//实际读入的字节数
77LPOVERLAPPEDlpOverlapped//指向一个OVERLAPPED结构
78);
//若返回TRUE则表明操作成功
79char*pReciveBuf;
80DWORDnWantRead=100,
81nReadRead;
82LPOVERLAPPEDm_OverlappedRead;
83BOOLbReadStatus=ReadFile(m_hComm,preciveBuf,nWantRead,&
nReadRead,&
m_OverlappedRead);
WriteFile()
来将资料写入Serialport.
84BOOLWriteFile(
85HANDLEhFile,//handletofiletowriteto
86LPCVOIDlpBuffer,//pointertodatatowritetofile
87DWORDnNumberOfBytesToWrite,//numberofbytestowrite
88LPDWORDlpNumberOfBytesWritten,//pointertonumberofbyteswritten
89LPOVERLAPPEDlpOverlapped//pointertostructureneededforoverlappedI/O
90);
ReadFile函数只要在串行口输入缓冲区中读入指定数量的字符,就算完成操作。
而WriteFile函数不但要把指定数量的字符拷入到输出缓冲中,而且要等这些字符从串行口送出去后才算完成操作。
当ReadFile和WriteFile返回FALSE时,不一定就是操作失败,线程应该调用GetLastError函数分析返回的结果。
例如,在重叠操作时如果操作还未完成函数就返回,那么函数就返回FALSE,而且GetLastError函数返回ERROR_IO_PENDING。
如果GetLastError函数返回ERROR_IO_PENDING,则说明重叠操作还为完成,线程可以等待操作完成。
有两种等待办法:
一种办法是用象WaitForSingleObject这样的等待函数来等待OVERLAPPED结构的hEvent成员,可以规定等待的时间,在等待函数返回后,调用GetOverlappedResult。
另一种办法是调用GetOverlappedResult函数等待,如果指定该函数的bWait参数为TRUE,那么该函数将等待OVERLAPPED结构的hEvent事件。
GetOverlappedResult可以返回一个OVERLAPPED结构来报告包括实际传输字节在内的重叠操作结果。
如果规定了读/写操作的超时,那么当超过规定时间后,hEvent成员会变成有信号的。
因此,在超时发生后,WaitForSingleObject和GetOverlappedResult都会结束等待。
WaitForSingleObject的dwMilliseconds参数会规定一个等待超时,该函数实际等待的时间是两个超时的最小值。
注意GetOverlappedResult不能设置等待的时限,因此如果hEvent成员无信号,则该函数将一直等待下去。
ClearCommError()
功能:
从字面上的意思看来,它是用来清除错误情况用的,但是实际上它还可以拿来取得目前通讯设备的一些信息.
91BOOLClearCommError(
92HANDLEhFile,//handletocommunicationsdevice
93LPDWORDlpErrors,//pointertovariabletoreceiveerrorcodes
94LPCOMSTATlpStat//pointertobufferforcommunicationsstatus
95);
在调用ReadFile和WriteFile之前,线程应该调用ClearCommError函数清除错误标志。
该函数负责报告指定的错误和设备的当前状态。
PurgeComm()
终止目前正在进行的读或写的动作
96BOOLPurgeComm(
97HANDLEhFile,//handleofcommunicationsresource
98);
参数说明:
HANDLEhFile,//串口名称字符串
dwFlags共有四种flags:
PURGE_TXABORT:
终止目前正在进行的(背景)写入动作
PURGE_RXABORT:
终正目前正在进行的(背景)读取动作
PURGE_TXCLEAR:
flush写入的buffer
flush读取的buffer
调用PurgeComm函数可以终止正在进行的读写操作,该函数还会清除输入或输出缓冲区中的内容。
GetCommMask()
得到设置的通信事件的掩码
99BOOLGetCommMask(
100HANDLEhFile,//handleofcommunicationsdevice
101LPDWORDlpEvtMask//addressofvariabletogeteventmask
102);
SetCommMask()
设置想要得到的通信事件的掩码
103BOOLSetCommMask(
104HANDLEhFile,//handleofcommunicationsdevice
105DWORDdwEvtMask//maskthatidentifiesenabledevents
106);
可设置的通信事件标志(即SetCommMask()函数所设置的掩码)
可以有EV_BREAK、EV_CTS、EV_DSR、EV_ERR、EV_RING、EV_RLSD、EV_RXCHAR、EV_RXFLAG、EV_TXEMPTY。
注:
若对端口数据的响应时间要求较严格,可采用事件驱动I/O读写,Windows定义了9种串口通信事件,较常用的有:
EV_RXCHAR:
接收到一个字节,并放入输入缓冲区。
EV_TXEMPTY:
输出缓冲区中的最后一个字符发送出去。
EV_RXFLAG:
接收到事件字符(DCB结构中EvtChar成员),放入输入缓冲区。
下面是MSDN上的解释:
EV_BREAKAbreakwasdetectedoninput.
EV_CTSTheCTS(clear-to-send)signalchangedstate.
EV_DSRTheDSR(data-set-ready)signalchangedstate.
EV_ERRAline-statuserroroccurred.Line-statuserrorsareCE_FRAME,CE_OVERRUN,andCE_RXPARITY.
EV_RINGAringindicatorwasdetected.
EV_RLSDTheRLSD(receive-line-signal-detect)signalchangedstate.
EV_RXCHARAcharacterwasreceivedandplacedintheinputbuffer.
EV_RXFLAGTheeventcharacterwasreceivedandplacedintheinputbuffer.Theeventcharacterisspecifiedinthedevice'
sDCBstructure,whichisappliedtoaserialportbyusingtheSetCommStatefunction.
EV_TXEMPTYThelastcharacterintheoutputbufferwassent.
WaitCommEvent()
等待设定的通讯事件的发生
107BOOLWaitCommEvent(
108HANDLEhFile,//handleofcommunicationsdevice
109LPDWORDlpEvtMask,//addressofvariableforeventthatoccurred
110LPOVERLAPPEDlpOverlapped,//addressofoverlappedstructure
111);
WaitCommEvent()会一直block(阻塞)到你所设定的通讯事件发生为止.
所以当WaitCommEvent()返回时,你可以由lpEvtMask取得究竟是那一事件发生,再来决定要如何处理.
WaitForSingleObject()
保证线程同步的等待函数
112DWORDWaitForSingleObject(HANDLEhHandle,//同步对象的句柄
113DWORDdwMilliseconds//以毫秒为单位的超时间隔,如果设为INFINITE,则超时间隔是无限的
114);
返回值 含义
WAIT_FAILED函数失败
WAIT_OBJECT_0指定的同步对象处于有信号的状态
WAIT_ABANDONED拥有一个mutex的线程已经中断了,但未释放该MUTEX
WAIT_TIMEOUT超时返回,并且同步对象无信号
WaitForMultipleObjects()
可以同时监测多个同步对象
115DWORDWaitForMultipleObjects(DWORDnCount,//句柄数组中句柄的数目
116CONSTHANDLE*lpHandles,//代表一个句柄数组
117BOOLbWaitAll,//说明了等待类型(),如果为TRUE,那么函数在所有对象都有信号后才返回,
118//如果为FALSE,则只要有一个对象变成有信号的,函数就返回
119DWORDdwMilliseconds//以毫秒为单位的超时间隔
120);
返回值 含义
WAIT_OBJECT_0到WAIT_OBJECT_0+nCount-1
若bWaitAll为TRU
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 异步 打开 串口 方法