[应用相关] STM32串口DMA接收出现ORE错误

[复制链接]
2103|5
 楼主| zljiu 发表于 2024-2-5 17:00 | 显示全部楼层 |阅读模式
1.事件背景

STM32中,使用USART配合DMA进行接收, 以标准库为例

//USART初始化

Void  Usart_Init(void)

{

        RCC_APB1PeriphClockCmd();//开启对应时钟

        RCC_APB2PeriphClockCmd();//开启对应时钟

        GPIO_Init();  //配置GPIO

        USART_Init();  //配置USART

        USART_ITConfig();  //配置中断

        USART_Cmd(USART1,ENABLE);//  使能USART,CR寄存器的UE位

}

//DMA初始化

Void  UsartRecDma_Init(void)

{

        RCC_APB1PeriphClockCmd();//开启对应时钟

        RCC_APB2PeriphClockCmd();//开启对应时钟

        DMA_Init();  //初始化DMA

        USART_DMACmd();  //USART和DMA链接

        DMA_ITConfig();  //配置中断

        DMA_Cmd();    //使能DMA

}

//主函数

Void main(void)

{

        Usart_Init();

        UsartRecDma_Init();

}

当Usart_Init()执行完后,外部设备向STM32的该串口发送一串字符,发送字符完成后再执行UsartRecDma_Init(),则导致STM32串口模块死机,且串口后续无法正常接收数据。

2.原因分析

STM32出现ORE过载错误,即USART_SR寄存器的ORE寄存器被置为1
3664065c0a38c2df00.png


3.解决方案

方案1:调整初始化顺序,USART的CR寄存器UE位开关留到最后打开,即完成USART和DMA的所有配置初始化后再使能USART。
603665c0a392a2387.png


//USART初始化

Void  Usart_Init(void)

{

        RCC_APB1PeriphClockCmd();//开启对应时钟

        RCC_APB2PeriphClockCmd();//开启对应时钟

        GPIO_Init();  //配置GPIO

        USART_Init();  //配置USART

        USART_ITConfig();  //配置中断

        USART_Cmd(USART1,DISABLE);//  关闭USART

}

//DMA初始化

Void  UsartRecDma_Init(void)

{

        RCC_APB1PeriphClockCmd();//开启对应时钟

        RCC_APB2PeriphClockCmd();//开启对应时钟

        DMA_Init();  //初始化DMA

        USART_DMACmd();  //USART和DMA链接

        DMA_ITConfig();  //配置中断

        DMA_Cmd();    //使能DMA

        USART_Cmd(USART1,ENABLE);//  使能USART,CR寄存器的UE位

}

//主函数

Void main(void)

{

        Usart_Init();

        UsartRecDma_Init();

}

方案2:定期检测ORE溢出错误,当出现ORE时通过读取寄存器,清空ORE标志。

//主函数

__IO  u16  reg = 0;

Void main(void)

{

        Usart_Init();

        UsartRecDma_Init();

        While(1)

        {

                if(0x08 == (USART1->SR & 0x08))

                {

                        reg = USART1->SR;

                        reg = USART1->DR;

                }

        }

}

方案3:在串口和DMA初始化的过程中,避免接收数据
————————————————

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

原文链接:https://blog.csdn.net/m0_49730102/article/details/134751888

梅花香自123 发表于 2024-2-22 18:46 | 显示全部楼层
通过将USART的CR寄存器的UE位的开关放在最后,确保在所有配置初始化完成后再使能USART,可以避免一些可能的冲突和错误。
梅花香自123 发表于 2024-2-22 19:08 | 显示全部楼层
定期检测ORE溢出错误,并在检测到ORE时通过读取寄存器来清空ORE标志,也是一种有效的处理方式。这样可以及时处理错误,并防止错误积累导致系统不稳定。
无法去污粉 发表于 2024-2-27 19:43 | 显示全部楼层
在串口和DMA初始化的过程中,避免接收数据可防止冲突
Henryko 发表于 2024-2-29 23:04 | 显示全部楼层
串口跟dma哪个优先级高啊
问天少年 发表于 2024-3-11 13:42 | 显示全部楼层
每次接收完都要清标志位
您需要登录后才可以回帖 登录 | 注册

本版积分规则

51

主题

3327

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部