wince串口工具的编写心得

来源:互联网 发布:淘宝衣服都是来自哪里 编辑:程序博客网 时间:2024/05/01 00:29

编写wince下串口工具的时候,在接收窗口用到了MFC的EDIT CTRL

1、网上发现了自动换行和自动滚屏的方法:

VC编辑框(EDIT)的自动换行与自动滚屏(转)

我使用的第二种方法,并且对EDIT的属性设置如下:

必须设置Vertical Scrollbar = TRUE
必须设置MultiLine = TRUE
必须设置Horizontal Scrollbar = FALSE
必须设置Auto HScroll = FALSE
可选设置Want Return = FALSE  
可选设置Auto VScroll = TRUE

方法一:(当EDIT映射到一CString时)
m_String = m_String + sNewString + "/r/n" //自动换行
UpdateData(false);

此法只能做到自动换行,不会自动滚屏到最后一行。

方法二:(当EDIT映射到一EDIT时)
m_Edit.SetSel(-1, -1); //自动滚屏
m_Edit.ReplaceSel(sNewString+"/r/n"); //自动换行
UpdateData(true);

此法可以做到自动换行,并自动滚屏到最后一行。

以上,m_String、m_Edit.分别为给编辑框添加的成员变量;sNewString 为要显示的字符串
注意二法中UpdataData参数的区别。

2、调试的时候遇到了个问题:

每次读完一个字节,接收下一个字节的时候,会对一下,对比hjb的串口工具,发现他的接收很快,哪怕调到1ms自动发送,而我的调到1ms自动发送,我的接收窗口就不显示了。另外一个有趣的发现是只要运行一下hjb的串口工具,再运行我的就OK,接收也很快,分析认为是有的地方我没有初始化,
最后终于发现,是COMMTIMEOUTS:COMMTIMEOUTS的关系:
介绍如下:
COMMTIMEOUTS:COMMTIMEOUTS主要用于串口超时参数设置。COMMTIMEOUTS结构如下:

typedef struct _COMMTIMEOUTS {
DWORD ReadIntervalTimeout;
DWORD ReadTotalTimeoutMultiplier;
DWORD ReadTotalTimeoutConstant;
DWORD WriteTotalTimeoutMultiplier;
DWORD WriteTotalTimeoutConstant;
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;


ReadIntervalTimeout:两字符之间最大的延时,当读取串口数据时,一旦两个字符传输的时间差超过该时间,读取函数将返回现有的数据。设置为0表示该参数不起作用。指定时间最大值(毫秒),充许接收的2个字节间有时间差。也就    是说,刚接收了一个字节后,等了ReadIntervalTimeout时间后还没有新的字节到达,就 认为本次读串口操作结束(后面的字节等下一次读取操作来处理)。即使你想读8个字节,但读第2个字节后,过了ReadIntervalTimeout时间后,第3个字节还没到。实际上就只读了2个字节。   


ReadTotalTimeoutMultiplier:指定比例因子(毫秒),实际上是设置读取一个字节和等待下一个字节所需的时间,这样总的超时时间为读取的字节数乘以该值,同样一次读取操作到达这个时间后,也认为本次读操作己经结束。   

ReadTotalTimeoutConstant:一次读取串口数据的固定超时。所以在一次读取串口的操作中,其超时为ReadTotalTimeoutMultiplier乘以读取的字节数再加上 ReadTotalTimeoutConstant。将ReadIntervalTimeout设置为MAXDWORD,并将ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant设置为0,表示读取操作将立即返回存放在输入缓冲区的字符。可以理解为一个修正时间,实际上就是按ReadTotalTimeoutMultiplier计算出的超时时间再加上该时间才作为整个超时时间。   

WriteTotalTimeoutMultiplier:写入每字符间的超时。

WriteTotalTimeoutConstant:一次写入串口数据的固定超时。所以在一次写入串口的操作中,其超时为 WriteTotalTimeoutMultiplier乘以写入的字节数再加上 WriteTotalTimeoutConstant。

一般都会做以下设置:
TimeOuts.ReadIntervalTimeout=MAXDWORD;
// 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作

TimeOuts.ReadTotalTimeoutMultiplier=0;
//读时间系数

TimeOuts.ReadTotalTimeoutConstant=0;
//读时间常量

TimeOuts.WriteTotalTimeoutMultiplier=50;
//总超时=时间系数*要求读/写的字符数+时间常量

TimeOuts.WriteTotalTimeoutConstant=2000;
//设置写超时以指定WriteComm成员函数中的




总结:我起初没有设置这个超时参数,导致使用过了一个默认的超时参数,1000ms,目前配置的方式如下:

COMMTIMEOUTS CommTimeouts;
GetCommTimeouts (hCom, &CommTimeouts);
//不使用这个逾时功能,ReadFile直到所有字符接收完才会返回
CommTimeouts.ReadIntervalTimeout = 10;//如果此值为0表示不使用功能,如果为10,则表示在10ms内没有接收到下一个字节,则认为超时,表示本次读串口操作结束
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
if (!SetCommTimeouts(hCom,&CommTimeouts) )
{
MessageBox(TEXT("Unable to set the time-out parameters!"),TEXT("Error!"), MB_OK);
return;
}
设置CommTimeouts.ReadIntervalTimeout =10ms
分析出错的原因:我在每次等到串口事件的时候我要读1024个字节,并且我没有设置超时参数,默认的是1秒的话,因此问题来了,假设我在1秒内发送了很多个字节,这时只要不大于1024个他就不会返回,也就是说不会显示,如果我在1秒内只发送了1个字节,那么它需要等待1秒确认没有下一个字节要接收的时候,才会返回本次的读串口操作,所以会觉得比hjb的慢,最后改参数为10ms就OK了,还是技术上掌握的不够全面不够深入。
原创粉丝点击