5 串口如何有效的清除掉接收缓冲,而不必一个一个的去读取

发布于 2020-07-23 23:59:30

目前,正在使用rtthread使用在项目编程中,现遇一些难题,实在想不到好的方法,加上系统编程经验欠缺,烦请教下,感谢不激,问题如下:

背景: 串口作为主机定时发送读取数据,然后等待从机返回数据。

现在串口做法程序如下:
while(1)
{

rt_thread_mdelay(5000);
encoder_t.send_buf[0] = 0x19;  /*读角度值*/     
rt_device_write(encoder_serial, 0,encoder_t.send_buf, 1);           
rec_size = 0;
result = rt_mq_recv(&encoder_mq, &rec_size, sizeof(rec_size), 100);
if(result == RT_EOK)  /*收到解析数据*/
{
    rx_len = rt_device_read(encoder_serial, 0, rx_buf, rec_size);
    rt_device_write(serial,0,rx_buf,rx_len);            
    if(rx_len > 6) 
    {
        parse_data((encoder_msg_typedef*)rx_buf);
    }
}

}
上面是一个处理线程,每隔5秒就发送19读取数据,然后等待接收后处理数据。这里程序使用了DMA空闲
中断回调函数里通知线程把数据接收过来。正常情况下是没有问题的,但对串口插座人为拨插几下。这时接
收数据就不正常了,连续接收5帧左右数据才变正常(使用了接收对列内存64btye),因为垃圾数据在接收缓存里没有处理,而发送指令时,然后等待接收是上一次的数据。显然这样就错误了。
问题一: 如何在发送指令前有效的清空掉接收里的缓冲数据?未见程序函数有清除操作。

    因为主机没有发送时,接收到的数据就应该是作废的。只有发送了,数据返回才能要.

查看更多

关注者
1
被浏览
205
2 个回答
JQRR_7669
JQRR_7669 认证专家 2020-07-24

使用

rt_serial_control(dev, TCFLSH, TCIOFLUSH);
苏华显
苏华显 2020-07-25

之前祼机编程时,在发送数据之前都会清空接收缓冲如下代码:
rec_cnt = 0; /接收计数清空/
rec_finish = 0; /接收完成标志清空/
send_data(buf, 10); /发送数据/

如果不清空,那么这前的数据会保留:
如之前有数据在接收缓冲区123,
那再次收到时数据时变成 123456,
显然,有时候我们不想这样,因为新的接收一帧是错误的,本来接收456数据才是正确。这对一问一答的协议非常不好,只有问了才应答,不问时,却收到了数据则要丢弃。
目前查看了源码并未有清除函数操作。但可以用读取函数来清空缓冲,效率可能低了些,经过测试,性能稳定。
读取接收清空操作:rt_device_read(serial, 0, buf,0,config.bufsz);
其中config.bufsz初始化时设置是接收最大接收量。
在中断回调函数里使用邮箱,邮箱只容纳一个邮件,邮件发送数据为串口DMA空闲接收到的一包数据的字节数量。经过优化后程序如下:
while(1)
{

rt_thread_mdelay(5);
rt_device_read(encoder_serial, 0, rx_buf,0,config.bufsz); /*清空接收数据缓冲,*/
rt_mb_recv(&encoder_mb,&rec_size,0);                      /*清空邮件*/
encoder_t.send_buf[0] = 0x19;                             /*读角度值*/     
rt_device_write(encoder_serial, 0,encoder_t.send_buf, 1);           
result = rt_mb_recv(&encoder_mb, &rec_size, 100);         /*接收等待超时100ms*/
if(result == RT_EOK)   
{
    rx_len = rt_device_read(encoder_serial, 0, rx_buf, rec_size);  /*接收数据*/   
    if(rx_len > 6) 
    {
        parse_data((encoder_msg_typedef*)rx_buf);  /*解析数据*/
    }
}

}
通过以上代码实现了祼机编程思路,如果觉得有用,可以参考,有写得不好,欢迎大家拍砖。

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友