最近在使用STM32F103串口功能时,发现第一个发出的串口数据帧总是不能被正确识别,在监听串口的原始报文后,我发现原来是数据帧前面多了一个0xFE。在经过一些尝试性的程序调整之后,我发现这个问题竟然和串口时钟初始化所在的位置有关。
这是存在问题的初始化程序:
/* GPIO Configuration */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA, &GPIO_InitStructure); /* USART configuration */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); USART_InitStructure.USART_BaudRate = u32BaudRate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); // Enable USART
这是修改后工作正常的代码:
/* GPIO Configuration */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOA, &GPIO_InitStructure); /* USART configuration */ USART_InitStructure.USART_BaudRate = u32BaudRate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); // Enable USART
这两者唯一的区别在于后者将串口时钟初始化放在了GPIO引脚初始化之前!
我现在还没有办法解释这种情况发生的原因,但是我推测是一些隐晦的时序问题导致串口数据线上产生了一个错误的数据,我还将进一步跟踪这个问题。(文中所用编译器为Keil MDK,有读者反应IAR无此问题,待测试验证)
>> 本文章版权归作者所有,如需转载请联系作者授权许可。
>> 原文来自: 云飞机器人实验室
>> 原文地址: STM32 | 串口初始化发送0xFE的Bug
>> 关于我们: 关于云飞实验室
>> 支持我们: 帮助我们可持续发展
我在发现 KEIL 的两个 Bug 之后就不再用它了 :roll:
1。你文中所诉的顺序问题。
2。当我定义并初始化一个端口的几个位之后,再继续定义并初始化这个端口的另外几位,发现前面的定义被覆盖掉了,无效了。好像一个端口要一次性定义似的。
你是用Keil编的吧,用IAR就没有这种顺序问题
是用Keil编译的,没有用过IAR编译,所以不知道IAR是什么情况。感谢指正。