BUG:在USART初始化过程中,USART的TX引脚莫名输出一个0xFF;
- 可能原因:GPIO口和USARTD的初始化顺序有问题,GPIO时钟 - GPIO - USART时钟 - USART
- 解决办法:调换GPIO和USART时钟的初始化顺序:GPIO时钟 - USART时钟 - GPIO - USART;
- 现象:
- 按照GPIO - USART时钟的顺序初始化时,发现在执行到开启USART时钟时,ESP8266会回发一个0xFF,推测是ESP8266认为STM32向其发送了0xFF(笔者通过串口向ESP8266发送0xFF时,其会回发0xFF);
- 怀疑ESP8266将电平波动误判为数据,在初始化USART时钟前加一个延时(等待TX引脚电平稳定):GPIO时钟 - GPIO - 延时 - USART时钟 - USART,发现串口输出数据变为0x00;
- 通过单步调试发现,当初始化TX的GPIO口和开启USART时钟之间没有延时的时候,USART输出0xFF,这两行之间有一定延时的时候,USART输出会变为0x00;怀疑这两次初始化之间的电平波动会使得ESP8266误判数据;
4. 将初始化顺序改成:GPIO时钟 - USART时钟 - GPIO - USART;串口在初始化过程中不再输出任何数据;
- 按照GPIO - USART时钟的顺序初始化时,发现在执行到开启USART时钟时,ESP8266会回发一个0xFF,推测是ESP8266认为STM32向其发送了0xFF(笔者通过串口向ESP8266发送0xFF时,其会回发0xFF);
- 具体原因分析
- 只要供电正常,ESP8266模块的RX口就处于时刻准备接收的状态;
- 如果在初始化GPIO为复用推挽输出模式(将GPIO_Pin的控制权交给外设)时还未初始化USART时钟,则会导致GPIO_Pin的电平处于不确定状态;
- 而GPIO初始化(GPIO_Init())和USART时钟初始化(AT_USARTx_APBxCLOCKCMD())的过程中,都会产生电平波动;此时TX引脚上的电平波动就有可能让ESP8266误认为有数据传输;电平时序如图所示
- 如果先初始化USART时钟再初始化GPIO外设为复用推挽输出模式,则GPIO_Pin的电平被USART确定(高/低),不会处于不确定的波动状态;