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
3.解决方案
方案1:调整初始化顺序,USART的CR寄存器UE位开关留到最后打开,即完成USART和DMA的所有配置初始化后再使能USART。
//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
|