Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
DMA
串口
serial_V2
串口v2+DMA接收
发布于 2023-12-29 11:03:20 浏览:1333
订阅该版
MCU使用的是STM32G0B1,串口使用V2版,DMA发送+接收,问题现象很奇怪,但已经初步定位,请大家一起讨论一下,有没有新思路。 所做的事很简单,串口调试助手每100ms发送一串数据,板子收到后转发回去。一开始的现象是随机发送n次后,就不再接收板子回复的数据了,像是进不去串口中断了,此时心跳灯正常。 ![screenshot_企业微信截图_17038169471051.png](https://oss-club.rt-thread.org/uploads/20231229/5e2688214a6911587246ca6459721156.png.webp) 由于板子只有485接口,没有msh,只能进debug对比了一下正常和问题时的寄存器状态 ![screenshot_企业微信截图_17038116437182.png](https://oss-club.rt-thread.org/uploads/20231229/7d00c328e06cbeabebdb76d05e721abf.png) 正常的时候FE为0,问题的时候是触发了FE,然后就想着清除看看,进到中断处理函数,发现是有相关操作的,但是貌似并未执行到: ```c if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_ORE) != RESET) { LOG_E("(%s) serial device Overrun error!", serial->parent.parent.name); __HAL_UART_CLEAR_OREFLAG(&uart->handle); } if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_NE) != RESET) { __HAL_UART_CLEAR_NEFLAG(&uart->handle); } if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_FE) != RESET) { __HAL_UART_CLEAR_FEFLAG(&uart->handle); } if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_PE) != RESET) { __HAL_UART_CLEAR_PEFLAG(&uart->handle); } ``` 这就奇怪了,再次debug,发现CR3中的EIE位就没开启,所以想着是不是需要开启错误中断才能进。好吧,那就开启EIE,在初始化的时候打开EIE: ```c // 使能FE __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_ERR); if (HAL_UART_Init(&uart->handle) != HAL_OK) { return -RT_ERROR; } ``` 还是不行。。。怒气值50+,中断也打开了,处理函数也有清FE,还有哪里没做到呢?想起来还有个回调函数,行,回调函数里面继续清: ```c void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { RT_ASSERT(huart != NULL); struct stm32_uart *uart = (struct stm32_uart *)huart; LOG_D("%s: %s %d\n", __FUNCTION__, uart->config->name, huart->ErrorCode); __HAL_UART_CLEAR_FEFLAG(&uart->handle); //UNUSED(uart); } ``` 还是不行。。。怒气值80+,这下是真没思路了,该做的都做了呀,还有哪里没想到呢?想不通那就继续debug吧,一路跑跑跑,突然发现怎么EIE没被置位呢?难道使能没起作用?终于在DMA的初始化那边发现了问题: ```c /* enable interrupt */ if (flag == RT_DEVICE_FLAG_DMA_RX) { rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx; RT_ASSERT(rx_fifo != RT_NULL); /* Start DMA transfer */ if (HAL_UART_Receive_DMA(&(uart->handle), rx_fifo->buffer, serial->config.rx_bufsz) != HAL_OK) { /* Transfer error in reception process */ RT_ASSERT(0); } CLEAR_BIT(uart->handle.Instance->CR3, USART_CR3_EIE); __HAL_UART_ENABLE_IT(&(uart->handle), UART_IT_IDLE); } ``` 第12行居然悄咪咪把EIE清零了!!!怒气值100!!!手动曹操盖饭!!! 把这一行注释了,现象有所改变: ![screenshot_企业微信截图_17038181924001.png](https://oss-club.rt-thread.org/uploads/20231229/7a96f93437cc16d20db0a75a69fa3321.png) F0的那一帧应该就是FE触发的那一帧。 目前为止解决了卡死的问题,清FE的操作是在中断函数内执行的,HAL_UART_ErrorCallback并未起到作用。 ![screenshot_企业微信截图_17038183533457.png](https://oss-club.rt-thread.org/uploads/20231229/00f849e24a814d8db5a3973248897c87.png) 目前有两点疑问: 1、为什么DMA要把EIE清掉? 2、为什么会出现FE,同样的环境我用自己写的驱动是不会出现FE的。是不是还有其他bug隐藏? 抛砖引玉,希望大家集思广益,一起出谋划策,把曹操盖饭拨回去。。。。 (以下是个人吐槽,之前一直用的是FREERTOS,作为一个任务调度器使用,并没有接管中断,驱动内中断部分还是自己实现的,自己的轮子其实跑的非常稳。对于RTT接管了中断重写我是不太理解的,RTT会比原厂处理中断更加专业吗?为什么不用原厂的中断处理呢?而且接管就彻底接管,串口这里只写了一部分,还有一部分没动,搞得不上不下的用起来很不爽。。。)
查看更多
2
个回答
默认排序
按发布时间排序
yangpengya
2023-12-29
这家伙很懒,什么也没写!
st版本老点的库不支持idle中断,所以接管了更方便。 现在st hal库已经有支持idle中断的API了,使用官方的确实要好点,这样也方便管理。 ```c /* 串口中断总入口 */ void HAL_UART_IRQHandler(UART_HandleTypeDef *huart); /* DMA中断总入口 */ void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma); /* IDLE中断API回调 */ void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size); /* 发送中断回调 */ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); /* DMA方式接收支持IDLE */ HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); /* 中断方式接收支持IDLE */ HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) /* DMA方式发送 */ HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); ```
开坦克的贝塔
2023-12-29
这家伙很懒,什么也没写!
我个人认为原作者`失能EIE`很大概率是偷懒, 先设置了DMA RX为一直循环接收, 再失能EIE, 这样只要处理`DMA的半满中断`和`全满中断`和`串口的IDLE中断`. 至于`Framing error`, 手册里是这样描述的: > This bit is set by hardware when a de-synchronization, excessive noise or a break character is detected. 就是说大概率是接线不良.
撰写答案
登录
注册新账号
关注者
1
被浏览
1.3k
关于作者
Ryanzz
这家伙很懒,什么也没写!
提问
1
回答
0
被采纳
0
关注TA
发私信
相关问题
1
串口DMA发送数据时,数据被覆盖
2
关于串口DMA模式下rt_device_close问题
3
利用stm32f427实现usb转串口,电脑端什么也没有识别到
4
finsh 控制台 适配 RS 485请大神指点????
5
uart_sample.c 中,读串口设备时偏移量pos要设置为-1而不是0?
6
【结贴】at_device软件包中对串口接收数据缺少判断导致数据接收异常
7
串口无法接受数据,但可以发送
8
串口如何有效的清除掉接收缓冲,而不必一个一个的去读取
9
串口接收使用方式问题
10
雅特力FINSH问题
推荐文章
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项目助手v0.2.0 - 支持Env Windows
2
RttreadV5.10上,GD32F450Z RTC时间显示问题
3
rt-smart启动流程分析
4
EtherKit快速上手PROFINET
5
RTThread USB转串口无法接收数据
热门标签
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
ESP8266
I2C_IIC
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
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部