Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
UART
如何清空系统下的串口中断接收buff stm32 RTT v2.0.3 【已解决】
发布于 2017-08-07 16:20:53 浏览:7056
订阅该版
项目需要通过串口传输大量数据到电脑上位机,但是由于数据量上来了,数据就难免会出错。为了纠正错误,我在程序中引入了校验机制,校验机制的工作流程如下: 下位机流程: 单片机发送一帧数据到上位机(6个字节,包含帧头数据校验和) -> 等待串口接收到反馈,若接收到校验成功反馈,就发送下一帧数据,否则重复发送本帧数据; 上位机流程: 接收一帧数据->判断帧头、校验和是否全部正确->全部正确则返回正确反馈(一个字节)以读取下一帧数据,错误则校验失败,放弃本次接收并反馈错误反馈; 校验部分的具体代码实现为: ``` rt_device_write(device2,0,&sendResult,6); //发送第一帧数据 while(1) { rt_device_read(device2,0,&tempBuff,1); //等待反馈回传 if(tempBuff == 0xe0) break; //正确反馈,退出校验发送下一帧 else if (tempBuff == 0xeb) rt_device_write(device2,0,&sendResult,6); //错误反馈,再次发送本帧数据 }``` 现在的问题是,第一帧数据发送完成后,接收到了正确的反馈,那么执行rt_device_read(device2,0,&tempBuff,1); 这句代码,每次得到的数值都是正确反馈0xe0,也就是说串口接收的buffer接收一次后设备每次读到的都是之前接收的那个值,于是就默认数据反馈成功,即便下次下位机发送数据,上位机没有任何反馈,下位机读buffer得到的仍然是校验正确,这使得校验无法完成。 请问各位,如何才能在设备访问usart之前,将系统的串口接收buffer清空? 补充说明一下,mcu是STM32F407ZE ,串口接收方式是中断接收,由系统函数rt_hw_serial_isr(&serial2, RT_SERIAL_EVENT_RX_IND);实现 2017年9月4日14:03:59更新: 该问题目前已解决,经过资料查询和多方请教,对RTT的串口机制终于有了比较彻底的了解; RTT系统层的串口设备BUFF是FIFO形式,每次读取全部数据之后就会清空缓存BUFF,在接收时通过判断rt_device_read(device2,0,&tempBuff,1)函数的返回值判断是否收到数据,收到数据再读出。 具体到我的代码上,造成该问题的原因并不是串口BUFF未清空,是我设置的20ms触发一次系统的软件定时器执行打断了串口的中断接收,在对接收数据代码优化为接收的时候关闭软件定时器,数据接收就不会再出错。 ![QQ截图20170828114337.png](https://oss-club.rt-thread.org/uploads/10129_885461d60f3c06e936ea845b8fd106e4.png)
查看更多
12
个回答
默认排序
按发布时间排序
pan16309
2017-08-23
这家伙很懒,什么也没写!
只有看没有回啊……问题并没有解决掉。上了系统之后串口协议真的是没法搞了……
aozima
2017-08-07
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
rt_device_read:你都不检查返回值,怪我咯 [s:194] 另外你的 while(1)没有阻塞机制,最终效果就是 while(1) 试想一下如果发送方不发了,或是线坏了。
aozima
2017-08-07
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
``` static rt_err_t _rym_rx_ind(rt_device_t dev, rt_size_t size) { if(sem) { rt_sem_release(sem); } //debug_printf("_rym_rx_ind "); return 0; } static int _rym_clean_up(rt_device_t dev) { char buf[1] = {0}; int count = 0; while (rt_device_read(dev, 0, buf, 1) == 1) { count++; if(count > 256) { return -1; } } return 0; } static enum rym_code _rym_read_code(rt_device_t dev, rt_tick_t timeout) { char buf[1] = {0}; /* Fast path */ if (rt_device_read(dev, 0, buf, 1) == 1) return (enum rym_code)buf[0]; /* Slow path */ do { rt_size_t rsz; /* No data yet, wait for one */ if (rt_sem_take(sem, timeout) != RT_EOK) return RYM_CODE_NONE; /* Try to read one */ rsz = rt_device_read(dev, 0, buf, 1); if (rsz == 1) return (enum rym_code)buf[0]; } while (1); } void foo(void) { _start: debug_printf("wait handshake ...... "); start = rt_tick_get(); retry = 3; while(1) { code = _rym_read_code(dev, RYM_CHD_INTV_TICK); end = rt_tick_get(); if(code == RYM_CODE_C) { break; } else { debug_printf("wait handshake C err: %s ", _get_code_name(code)); if( retry ) { retry--; continue; } if( (end - start) > (RYM_CHD_INTV_TICK * 10) ) { debug_printf("wait handshake timeout: %dms ", end-start); result = -RT_ERROR; goto _exit; } } } debug_printf("wait handshake C OK! need: %dms ", end-start); _rym_clean_up(dev); } ```
pan16309
2017-08-07
这家伙很懒,什么也没写!
>rt_device_read:你都不检查返回值,怪我咯 [s:194] > >另外你的 while(1)没有阻塞机制,最终效果就是 while(1) >试想一下如果发送方不发了,或是线坏了。 --- 不是读到buff里面再判断的吗,rt_device_read的返回值,根据手册只是返回读到的数据的实际大小吧。 我现在面临的问题是上面反馈了一个数据下去,下位机所有数据的校验都直接通过了,每次rt_device_read读到的都是第一次反馈的结果。 这个协议我在裸机上跑是没问题的,每次接收数据之前清空一下RX的buff就能保证握手成功。 至于while没有阻塞机制的问题,通讯正常了我会引入超时报错机制,倒不是什么大问题。
pan16309
2017-08-07
这家伙很懒,什么也没写!
>``` >static rt_err_t _rym_rx_ind(rt_device_t dev, rt_size_t size) >{ > if(sem) > { > rt_sem_release(sem); > } > > //debug_printf("_rym_rx_ind >"); > > return 0; >} > >static int _rym_clean_up(rt_device_t dev) >{ > char buf[1] = {0}; > int count = 0; > > while (rt_device_read(dev, 0, buf, 1) == 1) > { > count++; > > if(count > 256) > { > return -1; > } > } > > return 0; >} > >static enum rym_code _rym_read_code(rt_device_t dev, rt_tick_t timeout) >{ > char buf[1] = {0}; > > /* Fast path */ > if (rt_device_read(dev, 0, buf, 1) == 1) > return (enum rym_code)buf[0]; > > /* Slow path */ > do { > rt_size_t rsz; > > /* No data yet, wait for one */ > if (rt_sem_take(sem, timeout) != RT_EOK) > return RYM_CODE_NONE; > > /* Try to read one */ > rsz = rt_device_read(dev, 0, buf, 1); > if (rsz == 1) > return (enum rym_code)buf[0]; > } while (1); >} > >void foo(void) >{ >_start: > debug_printf("wait handshake ...... >"); > start = rt_tick_get(); > retry = 3; > while(1) > { > code = _rym_read_code(dev, RYM_CHD_INTV_TICK); > end = rt_tick_get(); > if(code == RYM_CODE_C) > { > break; > } > else > { > debug_printf("wait handshake C err: %s >", _get_code_name(code)); > > if( retry ) > { > retry--; > continue; > } > > if( (end - start) > (RYM_CHD_INTV_TICK * 10) ) > { > debug_printf("wait handshake timeout: %dms >", end-start); > result = -RT_ERROR; > goto _exit; > } > } > } > debug_printf("wait handshake C OK! need: %dms >", end-start); > _rym_clean_up(dev); >} >``` --- 这里的 clean_up 是把buff里的所有数据都读一次实现清空buff的意思吗?
一个潘一个锐
2017-08-23
这家伙很懒,什么也没写!
串口缓存是fifo原则,读了就释放了,为何要清空?
bernard
2017-08-24
这家伙很懒,什么也没写!
rt_device_read,不检查返回值基本上是作死的节奏。当串口未接收到数据时,调用这个函数也会直接返回的
pan16309
2017-08-28
这家伙很懒,什么也没写!
>rt_device_read,不检查返回值基本上是作死的节奏。当串口未接收到数据时,调用这个函数也会直接返回的 --- 加了检查返回值的代码,好像接收还是时对时错的 ``` if(temp == 0) { Spk_Beep(200); temp1 = rt_device_read(device1,0,&qrReadBuff,64); if(temp1 > 0x05) { rt_kprintf(" read = %s ",&qrReadBuff); memset(qrReadBuff,0,sizeof(qrReadBuff)); } } ``` 打印出来是这种效果(见截图)
bernard
2017-08-28
这家伙很懒,什么也没写!
做为字符设备,永远别考虑着,一次就能接收完整。
pan16309
2017-08-28
这家伙很懒,什么也没写!
>做为字符设备,永远别考虑着,一次就能接收完整。 --- 这不科学啊,我是应用在二维码扫描头上的,那意思是在操作系统下每次扫描都要扫描个四五次才能得到正常的数据?
撰写答案
登录
注册新账号
关注者
0
被浏览
7.1k
关于作者
pan16309
这家伙很懒,什么也没写!
提问
1
回答
10
被采纳
0
关注TA
发私信
相关问题
1
rt thread 2.0.2 usart 接收缓存问题
2
关于STM32串口通信的问题
3
STM32F1+RTT串口接收终端数据丢失问题
4
UART TX丢数据?
5
RTT打开串口的时候如何自定义波特率呢?
6
STM32F4的USART数据接收问题
7
串口1234使用问题
8
串口接收回调函数
9
LPC18xx UART问题讨论
10
x1000串口配置的失败问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
在RT-Thread Studio中构建前执行python命令
2
研究一了一段时间RTT,直接标准版上手太难,想用nano,但又舍不得组件
3
CherryUSB开发笔记(一):FSDEV USB IP核的 HID Remote WakeUp (USB HID 远程唤醒) 2025-01-18 V1.1
4
RT-thread 缩写字典
5
RT Thread 源码分析笔记 :线程和调度器
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
聚散无由
2
篇文章
14
次点赞
catcatbing
2
篇文章
4
次点赞
Wade
2
篇文章
2
次点赞
Ghost_Girls
1
篇文章
4
次点赞
xiaorui
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部