厦门莫格电气自动化有限公司销售
Honeywell霍尼韦尔620-3030
您迈开询价的一小步,我还您成功的一大步。
620-3030
620-3030
620-3030
异步串口(UART)通讯是嵌入式设备中***常见的通讯方式之一。本文主要针对预装Windows CE操作系统的英创主板,分析用户层程序在使用UART进行发送时的几个有关问题,供客户在设计应用程序时参考。
问题1:数据是否发送出去了?
WriteFile函数是发送串口数据的基本API,具体函数形式及参数定义如下:
BOOL WriteFile(
HANDLE hFile, //CreateFile返回函数Handle
LPCVOID lpBuffer, //装载发送数据的Buffer指针
DWORD nNumberOfBytesToWrite, //待发送数据的字节长度
LPDWORD lpNumberOfBytesWritten, //返回的实际发送的字节数
LPOVERLAPPED lpOverlapped // = NULL,CE未使用该参数
);
WriteFile的返回值为TRUE并不代表发送Buffer中的数据已全部发送出去了,需要检查返回的实际字节长度lpNumberOfBytesWritten。所以推荐的调用方法为
// 发送缓冲区pTxBuff, 发送长度dwLen
DWORD dwNumberOfBytesWritten = 0;
BOOL bRet = WrietFile(hFile, pTxBuf, dwLen, &dwNumberOfBytesWritten, NULL);
if(bRet && (dwLen == dwNumberOfBytesWritten))
{
//发送缓冲区中的数据已成功送入UART硬件的发送端口,大多数情况数据已从物理端口发送出去,但此时可能还有若干字节还在UART的硬件TX FIFO中,等待硬件控制器顺序发送。
//… 发送成功 …
}
else
{
//发送出错处理。。。。
}
问题2:WriteFile函数的阻塞问题
CE串口驱动的执行数据发送时,为了保持代码的***率,没有在驱动程序中层另外分配Buffer,把应用层需发送的数据先Copy到内部再发送,而是直接利用用户层的pTxBuf。因此原则上说,当数据没有发送完前,WriteFile函数是不会返回,处于阻塞挂起状态的。进一步,可能存在某种原因,数据始终没有发送完毕,则WriteFile将永远阻塞而不会返回。不少应用程序并不希望这样的永远阻塞,而是希望WriteFile能在一定时间内返回,即使出错,也让应用程序有机会进行出错处理。CE驱动为此专门设置了超时机制,其数据结构如下:
typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout; //与接收有关,本文不讨论
DWORD ReadTotalTimeoutMultiplier; //与接收有关,本文不讨论
DWORD ReadTotalTimeoutC***tant; //与接收有关,本文不讨论
DWORD WriteTotalTimeoutMultiplier; //发送超时倍数因子
DWORD WriteTotalTimeoutC***tant; //发送超时固定常数值
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
实际在驱动中,发送超时的计算及使用方法如下:
DWORD dwTimeout =
CommTimeouts.WriteTotalTimeoutMultiplier*dwLen +
CommTimeouts.WriteTotalTimeoutC***tant;
if ( !dwTimeout )
dwTimeout = INFINITE;
//等待来自发送中断线程的发送结束事件
ULONG WaitReturn = WaitForSingleObject(hTran***itEvent, dwTimeout);
上面的代码中dwTimeout的单位为ms,在***次打开串口驱动”COM#”时,超时数据结构中的WriteTotalTimeoutMultiplier和WriteTotalTimeoutC***tant均为0,所以就有发送超时无穷的问题。为了让dwTimeout为有限值,需要设置超时参数如下:
COMMTIMEOUTS CommTimeouts; //定义局部变量
GetCommTimeouts(hFile, &CommTimeouts); //读取串口的超时参数
//假设应用程序设置的串口波特率为baud
CommTimeouts. WriteTotalTimeoutC***tant = baud / BR9600 + 1;
CommTimeouts. WriteTotalTimeoutMultiplier =
CommTimeouts.WriteTotalTimeoutC***tant * 2;
SetCommTimeouts(hFile, &CommTimeouts); //重新设置串口超时参数
上述代码大致设置了一个2倍发送时间长度的超时时间,其中选取BR9600为单位时间,是因为9600bps波特率基本对应一个字节的发送时间为1ms。
ABB DAI04 9
3BSE013280R1 TU810V1 6
DPW01 5
DI620 5
DDI01 4
DDO02 4
DAI05 3
DI610 3
DO610 3
DRA02 3
DSAX452 3
DSDP170 3
PU515 3
IMASI23 3
37911-4-0338125 2
AO610 2
DSBC176 2
DSDX452 2
DSPC172H 2
DSQC322 2
DSQC352 2
IEMU11 2
NTCL01 2
PM630 2
PU515A 2
TC501V150 3BSC550038R3 2
TC514V2 2
PM511V16 1
AI625 2
07KT97B 1
35AE92 1
37911-4-0338124 1
3BSE 008538R1 1
3BSE013062R1 PU514 1
3BSE013231R1 TU811V1 1
3BSE032400R1 PU514A 1
3HAC0373-1 1
3HNE00313-1(含10米线及插头) 1
72395-4-0339123 1
AI610 1
CI625 1
CI810B 1
CM10/200 1
DAI01 1
DAI03 1
DAO01 1
DCP02 1
DCP10 1
DDI03 1
DDO01 1
DI814 1
DLM01 1
DO620 1
DO820 1
DSAI130 1
DSAI130D 1
DSAI145 1
DSAO110 1
DSAX 452 1
DSDX 452 1
DSIH 72VP ENOK 1
DSPC170 1*****************************************************************
DSPC172 1
DSQC327A 1
DSQC327A 1
DSQC354 1
DSQC503A 1
DSQC503A 1
DSQC539 1
DSQC602 1
DSQC603 1
DSQC608 1
DSQC658 1
DSTD108 1
DSU 14I 37911-4-0345659 1
EHDB280-21-11 1
PM510V16 1
PM632 1
PM645B 1
RDCO-01C 1
RVC6-5A 1
SNAT 7261 *** 1
TC512V1 1
IMASO11 1
IMDSO14 1
DSQC540 1
CI626V1 1
PM633 1
SC610 1
SC520 1
SC513 1
SB510 1
SR511 1
TC520 1
SC510 1
CI545V01 1
BB510(DC5256) 1
RF615 1
3HNE00313-1 1
FOXBORO 电源 53
FBM04 38
FBM202 37
P0400DL 30
P0500RG 31
FBM02 30
P0904FH 27
P0916AC 27
P0500RY 24
FBM201 23
FCM10E 22
FBM204 20
P0916AG 20
FBM03 18
FBM203 17
FBM01 16
FBM237 16
P0914XA 16
FBM242 15
FBM07 13
FBM217 12
P0961FR-CP60 11
P0961BC-CP40B 11
AD196BC 10
FBM214c 10
FPS400-24 10
P0916AA 11
P0800DC 9
P0950CA 9
P0960AW-CP30 9
FBM09 8
FBM12 8
FBM42 8
P0903ZE 8
FBM41 7
P0916JW 7
P0971WV-DNBT 7
P0400VE 6
FCM100Et 6
P0916AE 6
FBM02 5
P0500SR 5
P0914ZM 5
P0972PP-NCNI 5
P0961BD-GW30B 5
P0960HA 5
130K-N4-LLPF 4
FBM05 4
FBM207 4
P0700WB 4
P0916FJ 4
FCP270 4
P0961EF-CP30B 4
P0916JP 3
P0500RU 3
P0970BC-DNBT 3
P0400ZG 3
P0926CP-ZCP270 3
P0970VB 3
P0903CW 2
FBM206 2
FBM207B 2
FBM211 2
FCM10Ef 2
P0800DA 2
P0902YU 2
P0903NQ 2
P0903NW 2
P0903ZN 2
P0916NG 1
P0917MF 2
P0960JA-CP40 3
P0961CA 2
P0970EJ-DNBX 2
P0400VP-CMP10 2
FBI10E 2
FBM06 1
FBM07 1
FBM18 1
FBM214 1
FBM223 1
FBM224 1
K0143AA-P K0143AC-A 1
P0400VT 1
P0901VK 1
P0903MU 1
P0904BS 1
P0911VJ 1
P0912CA 1
P0916AW 1
P0916FK 1
P0926GH 1
P0970BC-DNBI 1
PO911*** 1
SRP981-BIDLS1NA 1
P0400HE 1
P0961FX-CP60S 1
P0916JS 1
FBM44 1
TRICON 3604E 11
3700 5
3003 5
3501E 5
3502E 5
3601E 5
3636R 5
3503E 4
4101 4
3607E 3
3805E 4
2658 2
3006 2
4119 2
3607E 2
3700A 2
4118 2
4500 2
4211 1
2058 1
2551 1
3008 1
3511 1
3625 1
3721 1
3511 1
3701 1