打印
[研电赛技术支持]

STM32/GD32——串口中断接收通信异常

[复制链接]
1473|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wowu|  楼主 | 2024-11-8 13:33 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、背景:
最近的工程使用到了串口通信,使用了中断接收和printf发送,中断接收的数据解析之后,将有用的数据,给到屏幕显示,屏幕用的是普通的LCD+LVGL显示。(GD32F303芯片)

1、做了一个界面的显示:背景图+文本+按钮,背景图文本字库均是存储在W25Q64(外部flash)内,然后在调试的过程中,我发现在使用屏幕刷新过程中,只要有LVGL在while循环内有刷新文本的操作就影响我串口数据的接收,直接导致了接收数据的缺失了。

2、例如我要接收一串完整的字符串为:<ABC|CDC:123,456|BBC:31.215|PID:1.5,2.3|>

中间总是会缺失几个字符,这就直接影响了我的解析函数,最后导致显示错误。

二、解决:
和很多人一样,我也是百度直接搜索 “串口和lvgl同时使用导致数据的丢失”,但是这样是搜不到有用信息的,于是乎就直接搜索关键词 “串口中断接收数据丢失/异常”,这就能看得一些经验贴了。例如以下的两篇参考:

参考1:GD32 串口接受异常的几个原因 - - 21ic电子技术开**坛

参考2:串口丢数据的几个常见原因 - 知乎

1、根据参考1,我测量了主板外部8M晶振,确认是正常的8M,内部调试查看到也是8MHz,排除晶振的影响。(排除)





2、使用编译器的调试器,我查看了内部寄存器的ORERR标志位不为1,没有过载,加上串口传输的数据量也不是很大,不存在接收数据溢出的情况,不会过载。(排除)



3、串口线过长导致的数据丢失或延迟,我这边使用的串口线是HDMI,数据RS232,大家都知道RS232主要就是提高抗干扰能力,增大通信距离。可能性不大,我自己我飞线出来接到串口调试助手看过,数据能完全接收过去,所以不可能。(排除)

说到这里就大概能排除串口硬件错误的原因了。

4、再来看一下软件原因:

(1)、查看工程中用到的所有外设中断的等级,看串口中断在接收过程中会不会被打断

(1)、中断分组
nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
/* 抢占优先级将分配 4 位,子优先级分配 0 位,即系统中的中断优先级完全由抢占优先级决定,子优先级不再使用。 */
(2)、外设等级设置
/* configure the systick handler priority */
nvic_irq_enable(SysTick_IRQn, 1, 0);       
/* 串口中断等级 */
nvic_irq_enable(DEBUG_UART_IRQn, 0, 0);

nvic_irq_enable(TIMER5_IRQn, 1, 0);
可以看到我的串口中断等级设置为最大,这说明,串口在接收过程中不会被其他中断打断,也不存在接收数据不及时。

所以中断等级不高的问题排除。

(2)、查看一下lvgl内部有没有影响中断的函数,比如说lvgl内部有中断和串口同等级,但是这个我没有找到,应该是没有影响到串口的代码。而且lv_tick_inc(1);函数是被我放在systick中的,基本也可以排除这个的影响。

5、既然中断等级问题被排除了,就考虑是不是整个工程哪里有关闭全局中断的函数了

__disable_irq();      // 关闭全部中断
全局搜索__disable_irq(); ,果然被我发现了在我使用W25Q64读取内部数据的时候使用到了SPI-DMA传输,里面是一个被我内部封装的函数。每次读取的时候都会关闭中断,然后再次开启,这就可以解释出,为什么每次串口中断的数据总是接收不完全。就是中断被关掉了!!!

为什么会一直读取W25Q64的内容?

因为在使用lvgl的绘制页面的时候,我有用到背景图和字库,这些数据就是存储在这个外部flash的,所以每次调用刷新函数的时候,总是会读取数据:





③  

最后删除掉这个__disable_irq(); 我的问题解决了。完美解决。

三、基础知识:
1、关闭中断和启用中断的函数知识:


Cortex-M3/M4内核NVIC及HAL库函数详解(5):__disable_irq和HAL_NVIC_DisableIRQ、__enable_irq和HAL_NVIC_EnableIRQ的区别_disableirq头文件-CSDN博客
2、串口配置知识:

GD32F303固件库开发(8)----USART收发配置 - 记帖 - 博客园

3、串口DMA不定长数据接收

GD32F30x的串口不定长DMA接收和DMA发送史诗级例子 - 单片机 - 硬汉嵌入式论坛 - Powered by Discuz!

小熊派gd32f303学习之旅(5)—使用DMA和空闲中断实现串口接收-CSDN博客

(PS:这些链接都是网上找的各位博主写的资料分享,感谢)
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/weixin_64192009/article/details/143516464

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

99

主题

4122

帖子

1

粉丝