本帖最后由 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,这个效率高些,因为你不必等到数据发送完。
 |