本帖最后由 huzi2099 于 2014-1-29 20:13 编辑
dwightwjl 发表于 2014-1-29 16:30 
谢谢解答~但是视频里老师说TC是发送完成,我自己感觉和你说的意思差不多额。我以为是初学,理解得还不是 ...
串口发送两个步子,
1: DR写入新的数据后新数据移送到移位寄存器,这个寄存器是看不到的,这步完成后TXE置位
2:移位寄存器合并起始位校验位等逐位发送,移位寄存器全部发完TC置位.
你为什么会丢B而不是A呢?因为你的初始进入循环条件不对也就是TC没有被清除,这时写入移位寄存器和DR都是空的写入是对的,也可以发送,但是注意手册上那句话要读一次SR再写DR才可以清除,所以写入字符A后检测TC是不对的,因此马上就会转到写入字符B,这次写入DR后会清除TC,因为USART_GetFlagStatus函数会读一次SR寄存器,代码如下
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
{
FlagStatus bitstatus = RESET;
/* The CTS flag is not available for UART4 and UART5 */
if (USART_FLAG == USART_FLAG_CTS)
{
assert_param(IS_USART_123_PERIPH(USARTx));
}
if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
后面再写入时就是这个顺序了读SR写DR都对了。加入延时之所以能对是因为1ms已经发送完了。
知道缘由解决就简单了,循环前空读一次SR就行了。
最好的方式还是把USART_GetFlagStatus放在USART_SendData(USART1, data);前面不会有错。
最好的写入时机还是检测TXE,这个效率高些,因为你不必等到数据发送完。
|