WinCE下串口接收问题!!!

时间:2020-12-27 03:58:54
 向GSM模块发送AT命令后,然后通过读线程读出模块响应。接收完后调用其他函数去处理接收到的数据,但是一次接收到的数据总是不完整的。例如发送AT,直接返回的是ATOK,但是每次总是先接收到AT或就一个A,就完了。要下一次才能接收到OK或TOK。 如何才能一次性接收到完整的响应呢???这个问题应该怎么解决呢????麻烦大家啦!

18 个解决方案

#1


这种情况应该是很普遍的,设定一个缓冲区,从缓冲区里读数据,读完以后清掉

#2


我之前也遇到过这种情况,很正常,我们有用两个DTU做点对点的通信测试,也会出现服务器方面接受到的数据帧不全,然后下一帧会把上一帧不全的数据给发过来!这个你要自己编写应对这种情况的代码,至于一次性接受到完整的数据,我也不清楚,帮不了你。

#3


不可能这么差的。
楼主用串口调试助手试试,如果也会这样,那是你串口驱动有问题。

#4


先检查一下串口的配置是否正确,增大一点儿输入缓冲区与输出缓冲区。如果仍旧没有解决,那就用多线程试试。

#5


谢谢各位了,但现在发现问题是,单步调试的时候串口能够读取完整的AT响应,并且再调用应用处理问题,没有任何错误。可是一连续运行,就有问题。这是怎么回事呢????麻烦各位帮帮忙呀~~

#6


你的串口优先级太低了吧?

#7


加延时

#8


被其它任务打断了吧。1.增高优先级。2.增加fifo的深度。

#9


呃,弱问一句,怎样提高优先级???

#10


引用楼主 kelanmn 的回复:
向GSM模块发送AT命令后,然后通过读线程读出模块响应。接收完后调用其他函数去处理接收到的数据,但是一次接收到的数据总是不完整的。例如发送AT,直接返回的是ATOK,但是每次总是先接收到AT或就一个A,就完了。要下一次才能接收到OK或TOK。 如何才能一次性接收到完整的响应呢???这个问题应该怎么解决呢????麻烦大家啦!


贴出你的代码看看,
你是怎么做的。一般都会采用WaitCommEvent 等待触发的,我这么做没有什么问题啊。
楼主这个数据量不大,是不是一些细节没有处理好。
http://blog.csdn.net/gooogleman/archive/2010/05/22/5615844.aspx
这里有我一些调试串口的一些经验,不知道是否对你有帮助了。呵呵。

#11


while (TRUE)
{   

  if(WaitCommEvent(ceSeries->m_hComm1,&evtMask,0))
{
SetCommMask (ceSeries->m_hComm1, EV_RXCHAR | EV_CTS | EV_DSR );
//表示串口收到字符
   if(evtMask & EV_RXCHAR) 
{
//清除错误并查询状态
ClearCommError(ceSeries->m_hComm1,&dwReadErrors,&cmState);
willReadLen = cmState.cbInQue ;//接收缓冲区中存储的待读取的字符数
if (willReadLen <= 0)
{
                    
continue;
}

readBuf = new BYTE[willReadLen+1];


ReadFile(ceSeries->m_hComm1, readBuf, willReadLen, &actualReadLen,0);
//如果读取的数据大于0,
if(actualReadLen> 0)

      WCHAR strmp[100]={0};
                      MultiByteToWideChar(CP_ACP,0,(char *)readBuf,actualReadLen,strmp,actualReadLen);
      ceSeries->m_strRespBuf+=strmp;
                   SetEvent(ceSeries->m_hATCmdRespEvent);
                   actualReadLen=0;
                 }
            }
}

#12


我就贴了接收部分,退出线程的事件响应就没贴了。还要贴哪些呢?
如果是串口优先级低了,怎么提高呢?????????谢谢前面的各位了~~~

#13


你还可以在一包数据内加一些判断字符来判断一帧全接收后再处理。比如加一个帧头、帧长度等,再把两个时间接收到的数据一起处理。

#14


根据你单步调试可以,我觉得是程序运行太快了,串口数据一返回(没有全部)就已经提交上来了。

程序不应该接到有数据就返回事件吧,而是等到接收到\r或\n结束符才返回事件

#15


使用缓冲区把,
我一般的做法是 使用一个缓冲区,
一直在接受串口数据,当接收到有串口数据后
定时器开始记时,
超过 50MS 没有收到数据就认为一个完整的包已经结束,
另外

AT 指令集邮一个结束标示包的啊~!
你也可以用结束标示包来判断啊~!

#16


串口的速率使用 115200 

#17


嗯,判断是否有结束符号,然后再激活事件。感觉一小问题绕了好远啊。。。。不过还有问题就是断开连接,也就是关闭线程,关闭串口后。我再按重新连接,这时候串口打开了,但是写入AT命令,读线程没有任何反应。等我断开后,又打开。这时候又可以了。反反复复都是这样循环的。这是怎么回事呢?

#18


详细点,没明白你的意思!

#1


这种情况应该是很普遍的,设定一个缓冲区,从缓冲区里读数据,读完以后清掉

#2


我之前也遇到过这种情况,很正常,我们有用两个DTU做点对点的通信测试,也会出现服务器方面接受到的数据帧不全,然后下一帧会把上一帧不全的数据给发过来!这个你要自己编写应对这种情况的代码,至于一次性接受到完整的数据,我也不清楚,帮不了你。

#3


不可能这么差的。
楼主用串口调试助手试试,如果也会这样,那是你串口驱动有问题。

#4


先检查一下串口的配置是否正确,增大一点儿输入缓冲区与输出缓冲区。如果仍旧没有解决,那就用多线程试试。

#5


谢谢各位了,但现在发现问题是,单步调试的时候串口能够读取完整的AT响应,并且再调用应用处理问题,没有任何错误。可是一连续运行,就有问题。这是怎么回事呢????麻烦各位帮帮忙呀~~

#6


你的串口优先级太低了吧?

#7


加延时

#8


被其它任务打断了吧。1.增高优先级。2.增加fifo的深度。

#9


呃,弱问一句,怎样提高优先级???

#10


引用楼主 kelanmn 的回复:
向GSM模块发送AT命令后,然后通过读线程读出模块响应。接收完后调用其他函数去处理接收到的数据,但是一次接收到的数据总是不完整的。例如发送AT,直接返回的是ATOK,但是每次总是先接收到AT或就一个A,就完了。要下一次才能接收到OK或TOK。 如何才能一次性接收到完整的响应呢???这个问题应该怎么解决呢????麻烦大家啦!


贴出你的代码看看,
你是怎么做的。一般都会采用WaitCommEvent 等待触发的,我这么做没有什么问题啊。
楼主这个数据量不大,是不是一些细节没有处理好。
http://blog.csdn.net/gooogleman/archive/2010/05/22/5615844.aspx
这里有我一些调试串口的一些经验,不知道是否对你有帮助了。呵呵。

#11


while (TRUE)
{   

  if(WaitCommEvent(ceSeries->m_hComm1,&evtMask,0))
{
SetCommMask (ceSeries->m_hComm1, EV_RXCHAR | EV_CTS | EV_DSR );
//表示串口收到字符
   if(evtMask & EV_RXCHAR) 
{
//清除错误并查询状态
ClearCommError(ceSeries->m_hComm1,&dwReadErrors,&cmState);
willReadLen = cmState.cbInQue ;//接收缓冲区中存储的待读取的字符数
if (willReadLen <= 0)
{
                    
continue;
}

readBuf = new BYTE[willReadLen+1];


ReadFile(ceSeries->m_hComm1, readBuf, willReadLen, &actualReadLen,0);
//如果读取的数据大于0,
if(actualReadLen> 0)

      WCHAR strmp[100]={0};
                      MultiByteToWideChar(CP_ACP,0,(char *)readBuf,actualReadLen,strmp,actualReadLen);
      ceSeries->m_strRespBuf+=strmp;
                   SetEvent(ceSeries->m_hATCmdRespEvent);
                   actualReadLen=0;
                 }
            }
}

#12


我就贴了接收部分,退出线程的事件响应就没贴了。还要贴哪些呢?
如果是串口优先级低了,怎么提高呢?????????谢谢前面的各位了~~~

#13


你还可以在一包数据内加一些判断字符来判断一帧全接收后再处理。比如加一个帧头、帧长度等,再把两个时间接收到的数据一起处理。

#14


根据你单步调试可以,我觉得是程序运行太快了,串口数据一返回(没有全部)就已经提交上来了。

程序不应该接到有数据就返回事件吧,而是等到接收到\r或\n结束符才返回事件

#15


使用缓冲区把,
我一般的做法是 使用一个缓冲区,
一直在接受串口数据,当接收到有串口数据后
定时器开始记时,
超过 50MS 没有收到数据就认为一个完整的包已经结束,
另外

AT 指令集邮一个结束标示包的啊~!
你也可以用结束标示包来判断啊~!

#16


串口的速率使用 115200 

#17


嗯,判断是否有结束符号,然后再激活事件。感觉一小问题绕了好远啊。。。。不过还有问题就是断开连接,也就是关闭线程,关闭串口后。我再按重新连接,这时候串口打开了,但是写入AT命令,读线程没有任何反应。等我断开后,又打开。这时候又可以了。反反复复都是这样循环的。这是怎么回事呢?

#18


详细点,没明白你的意思!