初级会员

- 积分
- 70
- 金钱
- 70
- 注册时间
- 2016-2-6
- 在线时间
- 19 小时
|
本帖最后由 qmcj 于 2016-3-1 12:25 编辑
现象:STM32 ZET6 硬件置位后,串口(USART)发送首字节数据丢;即硬件复位后,通过某个USART串口发送0x01、0x02、0x03,接收端只能接收到0x02、0x03, 0x01丢失;
原因分析:
u8 USART_data[] = {0x01、0x02、0x03};
for(t = 0; t < 3; t++)
{
USART_SendData(USART2, USART_LCD1[t]); //向串口2发送数据 语句A
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)!=SET); //等待发送结束 语句B
}
根本原因:Status register (USART_SR)寄存器,复位初始化为0x00C0,正好TC(Transmission complete)标志位复位后是置1的,表示发送完毕;这样就会导致,当第一次执行语句A后,紧接着语句B也进行了执行,查询后发现TC=1(表示第一个字节已经发送完成),再次执行语句A,发送第二个字节,导致第一个字节在没有被发送时就被第二个字节所覆盖;其实可以看出,第一个TC=1是由硬件置位引起的,并不是第一个字节(0x01)真正发送完成所置位的;因此,第一个字节丢失;
需要特别注意的是:TC的清零规则,根据(STM32英文参考手册,P811)可知有两种方式:1 先读USART_SR寄存器,再写USART_DR寄存器;2 向TC位写0清TC;上述的代码就是采用了第一种方式清TC,即语句B是读USART_SR,语句A是写USART_DR寄存器;所以语句中并没有向TC位写0的语句;
解决“硬件置位,USART发送首字节丢失”方法:
1 在硬件置位后,语句A前,通过向TC位写0,来清TC位;即在语句A前加:USART_ClearFlag(USART2,USART_FLAG_TC);
2 在硬件置位后,语句A前,通过读取USART_SR寄存器以及后续的原有语句写USART_DR来清TC;即在语句A前加:USART_GetFlagStatus(USART2, USART_FLAG_TC);
3 语句A后给予短暂的时延,使得第一个字节真正被发送后,在进入循环发送(此方法其实有问题,不推荐)
|
|