Windows CE嵌入式高级编程及其实例详解10.docx
《Windows CE嵌入式高级编程及其实例详解10.docx》由会员分享,可在线阅读,更多相关《Windows CE嵌入式高级编程及其实例详解10.docx(82页珍藏版)》请在冰豆网上搜索。
WindowsCE嵌入式高级编程及其实例详解10
第10章串口编程
串口是计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,因此应用
非常广泛。
例如在工业自动化中,很多智能采集设备都是采用串口方式和PC机进行通讯。
在
WindowsCE嵌入式电脑中,串口依然是和外部设备进行通讯的重要方式,例如GPS设备。
目
前很多PDA都集成了蓝牙通讯功能,可以通过设置蓝牙通讯方式为串口方式,来和另外一端
蓝牙设备进行通讯。
作为一名WindowsCE程序编写人员,掌握串口编程知识,将会为日后工
作提供极大的便利。
本章主要包括如下内容:
·串口概述
·串口编程APl函数介绍
·串口综合示例
·’GPS编程示例
10.1串口概述
“串行通信”是指外设和计算机间使用两根数据信号线(另外需要地线,可能还需要控制
线),数据在一根数据信号线上一位一位地进行传输,每一位数据都占据一个固定的时间长度。
这种通信方式使用的数据线较少,在远距离通信中可以节约通信成本,而且其传输速度也不比
并行传输的速度慢。
相反的,“并行通信”是指一条信息的各位数据被同时传送。
并行通讯的
特点是:
各数据位同时传送、传送速度快、效率高,但由于有多少数据位就需多少根数据线,
因此传送成本较高,比较适用于近距离(相距数米)的通讯。
目前较为常用的串口有9针串口(DB9)和25针串口(DB25),当通信距离较近时(<12m),
可以使用电缆线直接连接标准RS232端口(RS422和RS485较远),若通信距离较远,则需附
加调制解调器(Modem)。
表10.1将简要说明DB9常用信号脚定义。
表10.1DB9常用信号脚说明表
9针串口(DB9)
25针串口(DB25)
针号
功能说明
缩写
针号
功能说明
缩写
l
数据载波检测
DCD
8
数据载波检测
DCD
2
接收数据
RXD
3
接收数据
RXD
3
发送数据
TXD
2
发送数据
T)(D
4
数据终端准备
DTR
20
数据终端准备
DTR
5
信号地
GND
7
信号地
GND
续表
9针串口(DB9)
25针串口(DB25)
针号
功能说明
缩写
针号
功能说明
缩写
6
数据设备准备好
DSR
6
数据准备好
DSR
7
请求发送
RTS
4
请求发送
RTS
8
清除发送
CTS
5
清除发送
CTS
9
振铃指示
DELL
22
振铃指示
DELL
最简单且常用的接线方式是三线制接法,即地、接收数据和发送数据三脚相连,即只要有接
收数据针脚和发送针脚就能实现串口数据传输;对于同一个串口,只要接收脚和发送脚直接用线
相连,那么在此串口发送什么数据,该串口就可以接收什么数据。
对于两个不同串口(不论是同
一台计算机的两个串El或分别是不同计算机的串13),均可以采用如表l0.2所示的接线方式。
表10.2不同串口接线方式表
9针一9针
25针-25针
9针-25针
2
3
3
2
2
2
3
2
2
3
3
3
5
5
7
7
5
7
对于
口硬件介
1.打
在访肛
开串口,有
函数打开目
码中,将赫
HANDL
第10章串口编程
353
在此需要说明的是,在CreateFile函数的参数中,共享参数必须设置为0,表示独占方式;
安全参数必须设置为NULL值;模板文件参数也必须被设置成NULL。
由于在WindowsCE中,不支持重叠I/O模式,因此不能在参数dwFlagsAndAttributes中
传递FILEFLAGOVERLAPPED。
’
如果打开串口成功,将返回打开串口的句柄,否则将返回INVALIDHANDLEVALUE。
打开串口之后,串口就已经被独占了,因此当不再使用已打开的串口时,应及时关闭串
口,此时可以使用CloseHandle函数关闭串口。
例如可以使用以下代码来关闭上面打开的串口:
BOOLbResult=CloseHandle(hComm);
2.配置串口
在使用串口和另外一个设备进行通讯时,一定要先设置串口的参数(波特率、奇偶校验、
数据位等),这些参数设置正确与否将直接影响是否能够和串口设备进行通讯。
串口参数信息
一般由串口设备厂家提供。
WindowsCE中提供了GetCommState和SetCommState函数,分别
用于获取串口的当前参数和设置串口的参数,它们的定义如下:
B00LGetCommState(
HANDLEhFile,
LPDCBIpDCB);
BOOlJSetCommStatef
HANDLEhFile,
LPDCBIpDCB)j
这两个函数都包含了相同的参数,其中参数hFile是输入参数,指向已打开的串口句柄;
参数IpDCB指向DCB结构的指针,在GetCommState函数中,它属于输出参数,在SetCommState
函数中,它属于输入参数。
DCB结构完全描述了串口的使用参数,它的定义如下:
typedefs
DWORDDC
I
DWORDBa
DWORDfB
tructDCB{
B1enqth
udRate;
inary:
1
//DCB结构大小
//波特率
//_-进制模式
DWORDfParity:
1;//进行奇偶校验
DWORDfOutxCtsFlow:
1;//使CTS信号进行输出流量控制
DWORDfOutxDsrFlow:
1j//使DSR信号进行输出流量控制
DWORDfDtrControl:
2;//DTR流量控制
DWORDfDsrsensitivitv:
1;//DSR敏感度
DWORDfTXContinueOnXoff:
b//XOFF后是否继续发送
DWORDfOutX:
1;//使得输出XON/XOFF有效
DWORDfInX:
l;//使得输入XON/XOFF有效
DWORDfErrorChar:
1j//允许奇偶错误替换
DWORDfNull:
l;//允许删除NULL
DWORDfRtsControl:
2j//RTS流量控制
DWORDfAbortOnError:
1j//出错时是否终止读写操作
DWORDfDummy2:
17;//保留
WORDwReserved;//当前未用,必须置为0
WORDXonLim;//XON阈值
WORDXoffLim;//XOFF阈值
charEvtChar;jf萼懈导符
WORDwReservedl;//保留,未用
)DCB;
·成员DCBlength指定了DCB结构大小。
·成员BaudRate指定了串口设备的传输速率。
波特率的范围一般是从每秒110位到每
秒256000位。
·成员fBinary必须被设置TRUE,因为在CE中不支持非二进制的串行传输模式。
·成员fParity表示启用奇偶校验,该值一般被设置TRUE,以便启用奇偶校验。
、
·成员fOutxCtsFlow用于指定CTS(Clear—T0.Send)信号是否被监视并作为输出流
量控制信号。
如果此成员被设置为TRUE并且CTS信号被关闭,则输出被挂起,直
到CTS信号重新发出。
·成员fOutxDsrFlow用于指定DSR(Data—Set—Ready)信号是否监视并作为输出流
量控制信号。
若此成员被设置TRUE,并且DSR信号被关闭,则输出被挂起,直到
DSR信号重新发出。
·成员fDtrControl指定DTR(Data—Terminal.Ready)信号作为流量控制,此成员可以
是表l0.3中列出的值。
表10.3fDtrControl成员取值表
值
描述
DTR——CONTROL——DISABLE
当串口设备打开时,DTR信号线始终设为禁止
DTR——CONTROL——ENABLE
当串口打开时,DTR信号线设为使能并始终打开
DTR——CONTROL——HANDSHAKE
使DTR支持握手,此时可调用EscapecommFunction函
数来释放DTR线上的错误
第10章串口编程
355
输入缓冲区中存有数据的空间达到XoffLim定义的字节数时,XoffChar将被发送;
当输入缓冲区中可用的空间达到XonLim定义的字节数时,XonChar被发送。
成员fErrorChar指定当收到的字符发生奇偶校验错误时,是否使用ErrorChar成员定
义的字符代替。
若此成员设为TRUE且fP撕够成员为TRUE,将会发生替换。
成员fNull指定null是否被丢弃。
若此成员设为TRUE,则接收到的NULL字符被放弃。
成员fRtsControl指定RTS(request-to-send)流量控制。
若此值为0,则缺省值为
RTSCONTROLHANDSHAKE。
表l0—4歹0出了该成员的可用值。
表10-4fRtsControl成员的可用值表
值
描述
RTS——CONTROL——DISABLE
当串口设备打开时,RTS线始终为禁止
RTS—.CONTROL——ENABLE
当设备打开时,RTS线始终设为使能并始终打开
RTS——CONTROL——HANDSHAKE
启用RTS握手功能。
当输入缓冲区字符小于缓冲区总数的1/2时,驱
动程序使RTS信号为高,超过3/4时,使RTS信号为低。
若RTS握手
功能可用,可调用EscapeCommFunction函数释放DTR线上的错误
RTS——CONTROL——TOGGLE
指定当发送数据时,RTS信号线为高,缓冲区数据发送完,RTS信号
线为低
●
成员fAbortOnError指定当错误发生时,读写操作是否终止。
若此成员设置为TRUE,
则当错误发生时,所有的读写操作将终止,直到应用程序识别错误并调用
ClearCommError函数后,驱动程序才进行更深层次的通讯。
成员fDummy2保留,未用。
成员wReserved未用,必须置为0。
成员XonLim指定发送XON字符前输入缓冲区允许的最小字节数。
成员XoffLim指定发送XOFF字符前输入缓冲区允许的最大字节数。
最大允许接收
字符数可以用定义的全部输入缓冲区字节数减去此值得到。
成员ByteSize指定每字节发送接收的位数。
成员Parity指定奇偶校验方法。
表l0—5列出了该成员的可用值。
表10-5Parity成员的可用值表
值
描述
EVENRUUTY
偶校验
MARKpARTTY
标记校验
NORUUTY
无校验
ODDBUUTY
奇校验
SPACEPfUUTY
Space
·成员StopBits用于指定停止位的位数。
该成员的可用值如表l0-6所示。
·成员XonChar指定发送接收的XON字符。
·成员XoffChar指定发送接收的XOFF字符。
·成员ErrorChar指定当接收的奇偶校验错误时被代替的接收字符。
356WindowsCE嵌入式高级编程及其实例详解(用c++实现)
表10-6StopBits成员可用值表
值
描述
ONESTOPBIT
1位停止位
1ⅢE5STOPBITS
1.5位停止位
TWOSTOPBITS
2位停止位
·成员EofChar指定某字符作为数据结束标记。
·成员EvtChar指定某字符作为事件标记。
·成员wReserved被保留,未用。
在设置串口参数时,最好先用GetCommState函数得到串口的当前参数,然后再修改需要
设置的成员。
3.读、写串口
正如使用CreateFile函数打开串口一样,开发人员同样可以使用ReadFile和WriteFile函
数读取串口数据和向串口中写入数据。
关于ReadFile和writeFile函数的介绍,请参考第6章
文件编程中的介绍。
这里需要注意的是,由于从串口中读写数据的速度比较慢,因此不要试图在主线程中读
写大量数据,这样会阻塞主线程中处理主窗体的消息队列,最好的方法就是用单独的线程来读
写数据。
在下面的串口综合使用示例中将会介绍ReadFile和WriteFile函数的具体用法。
4.异步串口I/O
虽然WindowsCE中不支持重叠I/O操作,但还是可以分别用单独的线程去读写串口,通
过多线程来模拟重叠操作。
同时WindowsCE还提供了WaitCommEvent函数,该函数将阻塞
线程,直到预先设置的串口事件中的某一事件发生。
在后面的串口综合使用示例中将会介绍
WaitCommEvent函数的使用。
在使用串口事件前,还需要了解如下三个函数:
.
BOOLGetCommMask(HANDLEhFile,LPDWORDipEvtMask);
BOOLSetCommMask(HANDLEhFile,DWORDdwEvtMask);
BOOLWaitCommEvent(HANDLEhFile,LPDWORDIpEvtMask,LPOVERLAPPEDlpOVerlapped);
·GetCommMask函数用于得到串口已经设置了的串口事件,参数hFile指定已打开的
串口句柄,参数lpEvtMask用于存取得到串口事件集。
·SetCommMask函数的功能与GetCommMask函数相反,用于设置串口事件集。
·WaitCommEvent函数用于等待预先设置的串口事件中的某一事件发生。
参数
lpEvtMask用于存储已经的发生事件;参数lpOverlapped必须被设置NULL,因为在
WindowsCE中不支持重叠结构。
上面三个函数中的第2个参数,即串口事件集,它可以是表l0—7中的某个值或其中组合。
表10.7串口事件表
值
描述
EV——BREAK
检测到中断发生
EVCTS
CTS改变了状态
EVDSR
DSR信号改变了状态
第10章串口编程
357
续表
值
描述
EVERR
串口驱动程序检测到了错误
EVRING
检测到振铃
EVRLSD
RLSD行改变了状态
EV——RXCHAR
接收到了一个字符
EV——RXFLAG
接收到了一个事件字符
EV——TXEMPTY。
在输出缓冲区中的最后~个字符被发生
5.设置端口读写超时
在调用ReadFile和WriteFile函数从串口读取数据和写入数据时,WindowsCE提供了超时
机制,也即是设置了等待它们返回的时间长度。
设置串口超时函数SetCommTimeouts的定义
如下所示:
BOOLSetCommTimeoutS(
HANDLEhFile,
LPCOMMTIMEOUTSlpCommTimeouts)j
·参数llFile指向已经打开的串口句柄。
·参数lpCommTimeouts指向COMMTIMEOuTS结构,设置新韵超时值。
COMMTIMEOUTS结构定义如下:
typedefstruct—COMMTIMEOUTS{
DWORDReadIntervalTimeout;
DWORDReadTotalTimeoutMultiplier;
DWORDReadTotalTimeoutConstant;
DWORDWriteTotalTimeoutMultiplier;
DWORDWriteTotalTimeoutConstant;
)COMMTIMEOUTS,+LPCOMMTIMEOUTS;
读超时的计算方法有两种,一种超时是ReadIntervalTimeout指定了在接收字符间的最大
时间间隔,如果超过了这个时间,ReadFile函数立刻返回;另一种超时是基于要接收的字符数
量,ReadTotalTimeoutMultiplier表示平均读一字节的时间上限,ReadTotalTimeoutConstant表
示读数据总超时常量。
第二种读数据超时可用如下等式表示:
读数据总超时=ReadTotalTimeoutConstant+(ReadTotalTimeoutMultiplier*要读的字节数)
写超时计算方法与读超时的第2种计算方法相似,WriteTotalTimeoutMultiplier表示平均写
一字节的时间上限,WriteTotalTimeoutConstant表示写数据总超时常量,总超时计算方法如下:
写数据总超时=WriteTotalTimeoutConstant+(WriteTotalTimeoutMultiplier*要写的字节数)
对于读数据超时,第一种超时(间隔超时)和第二种超时(总超时)同时有效,当出现
任何一种超时时,都将返回。
下面是详细的超时值设置:
·有读间隔超时、读总超时和写总超时:
将COMMTIMEOUTS结构中的五个成员设置
为相应值。
·有读总超时和写总超时,但没有读间隔超时:
将ReadIntervalTimeout设置为0,将其
黔——叩一
358windowscE嵌入式高级编程及其实例详解(用c++实现)——
————_——————————————_—————————————————————————————————————————————————————一
他字段设置为相应值。
·不管是否有数据要读取,ReadFile立刻返回:
将ReadIntervalTimeout设置成
MAXDWORD,将ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都设置
成0。
·ReadFile没有超时设置,直到有适当的字符数返回或错误发生,该函数才返回:
将
ReadInteⅣalTimeout、ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant值都设
置为0。
·writeFile没有超时设置:
将WriteTotalTimeoutMultiplier和WriteTotalTimeout_Constant
都设置成0。
对于串口读写,以上所介绍到的超时操作是至关重要的。
读者可以根据实际情况考虑采
用何种超时操作。
如果从串口读取数据和写入数据都采用超时,最好采用单独的线程负责读取
和写入,以使不会阻塞主线程。
WindowsCE还提供了SetupComnl函数来设置接收和发送数据的缓冲区的大小。
它的定
义如下:
。
BOOLSetupComm(
HANDLEhFile,
DWORDdwInQueue,
DWORDdwOutQueue);
·参数hFile指定已经打开的串口句柄。
·参数dwlnQueue和dwOutQueue指定接收和发送缓冲区的大小。
SetupConlm并不推荐使用,因为系统会推荐一个适合的默认值。
6.控制串口
WindowsCE提供了SetCommBreak函数,用于停止传输字符并将串口置于中断状态,还
提供了ClearC0删:
llBreak用于重新传输字符。
SetCommBreak和ClearCommBreak函数的定义
如下:
BOOLSetCommBreak(
HANDLEhFile);
BOOLClearCommBreak(
HANDLEhFile);
以上两个函数都只有唯一的入口参数hFile,表示已打开的串口句柄。
7.清空串口缓冲区
WindowscE提供了PurgeComm函数用于清空串口的发送缓冲区和接收缓冲区,
PurgeComm函数的定义如下:
BOOLPurgeComm(
HANDLEhFile,
DWORDdwFlags)j
·参数hFile表示打开的串口句柄。
·参数dwFlags表示操作类型,在WindowsCE下该参数有如下两种取值。
>PURGETXCLEAR:
清空发送缓冲区。
>PURGERXCLEAR:
清空接收缓冲区。
第10章串口编程
359
这两个值可以组合使用,表示同时执行清空发送缓冲区和接收缓冲区的功能。
8.清除错误并查询状态
WindowsCE还提供了一个非常有用的函数ClearCommError,用于清除驱动程序产生的任
何错误状态并返回当前窗口状态,该函数定义如下:
BOOLClearCommError(
HANDLEhFile,
LPDWORDipErrors,
LPCOMSTATipStat);
·参数hFile指向已经打开的串口句柄。
·参数lpErrors表示发生的错误码,它的值将是表10.8中的任意一个值或组合。
表10—8IpErrors参数取值表
错误码
描述
CE—BREAK
硬件检测到了一个中断条件
CE—FRAME
硬件检测到一个帧错误
CEl0E
硬件通讯时发生一个I/O错误
CE——MODE
请求模式未被支持,或者hFile参数无效。
如果这个值被指定,它
就是仅有的合法错误
CE—OVERRUN
一个字符缓冲区侵占发生,下一个字符被丢失
CE——RXOVER
输入缓冲区溢出发生,或者输入缓冲区无空间,或者在收到End—
Of—File(EOF)字符之后又收到字符
CE——RXPARITY
硬件检测到奇偶校验错误
CE—TXFULL
应用程序试图发送一个字符,但是输出缓冲区已满
·参数lpStat指向COMSTAT结构,用于存储当前窗口的状态。
COMSTAT结构的定义
如下所示:
●
●
●
●
tvPedefStructCOMSTAT{
DWORDfCtSH01d:
1;
DWORDfDsrH01d:
1;
DWORDfRlSdH01d:
1;
DWORDfXOffH01d:
1;
DWORDfXoffSent:
1;
DWORDfEof:
1;
DWORDfTxim:
1j
DWORDfReserved:
25;
DWORDcbInQue;
DWORDcbOutQue;
}COMSTAT,+LPCOMSTATj
前5个字段表示串口传输是否因为它的原因而等待。
字段fCtsHold表示是否等待CTS信号。
字段ff)srHold表示是否等待DSR信号。
字段fRlsdHold表示是否等待“接收线路信号检测,也叫载波检测”。
字段tXoffHold表示是否等待XOFF字符。
字段fXoffSent表示是否因为驱动程序发送XOFF字符而等待。
字段fEof表示是否收到串口尾部字符。
字段fTxim如果是1,表示队列中的字符是由TransmitCommChar函数写入的而不
WriteFile函数。
·