极海半导体APM32F103 USART——TXC和TSBE的区别及应用注意点
 极海半导体推出的APM32F103 USART——TXC和TSBE的区别及应用注意点:
1 遇到问题
在使用USART轮询发送数据完成后进入待机模式,会出现最后1个字节无法完整发送完成的情况,经过实验后,是标志位的选择不合理。
以下记录了“发送数据完成标志”、“发送数据缓冲器为空标志”的学习、调试过程。

2 寄存器定义

3 实验现象3.1 使用“TXBE”正常发送3个字节数据
  
关键代码
  
USART_TxData(USART1, '1');
  
while(USART_ReadStatusFlag(USART1,  USART_FLAG_TXBE) == RESET);
现象
 
结论
数据未完全发送完,标志位已置1

3.2 使用“TXC”正常发送3个字节数据
  
关键代码
  
USART_TxData(USART1, '1');
  
while(USART_ReadStatusFlag(USART1,  USART_FLAG_TXC) == RESET);
现象
 
结论
在每一个字节发送完成后再置1

3.3 使用“TXBE”正常发送3个字节数据后立刻进入standby模式
  
关键代码
  
USART_TxData(USART1, '1');
  
while(USART_ReadStatusFlag(USART1,  USART_FLAG_TXBE) == RESET);
  
  
PMU_EnterSTOPMode(PMU_REGULATOR_ON,PMU_STOP_ENTRY_WFI);
现象
 
结论
无法发完数据

3.4 使用“TXC”正常发送3个字节数据后立刻进入standby模式
  
关键代码
  
USART_TxData(USART1, '1');
  
while(USART_ReadStatusFlag(USART1,  USART_FLAG_TXC) == RESET);
  
  
PMU_EnterSTOPMode(PMU_REGULATOR_ON,PMU_STOP_ENTRY_WFI);
现象
 
结论
可以发完数据

4 实验程序
//#define TEST_TXC
#define TEST_TXBE
 
int main(void)
{
    uint8_ti;
 
   GPIO_Config_T GPIO_ConfigStruct;
   GPIO_Config_T Trigger_GPIO_ConfigStruct;        
   USART_Config_T USART_ConfigStruct;
 
   RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOA |RCM_APB2_PERIPH_USART1));
   RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOC));
 
   Trigger_GPIO_ConfigStruct.mode = GPIO_MODE_OUT_PP;
   Trigger_GPIO_ConfigStruct.pin = GPIO_PIN_0;
   Trigger_GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
   GPIO_Config(GPIOC, &Trigger_GPIO_ConfigStruct);
 
   GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
   GPIO_ConfigStruct.pin = GPIO_PIN_9;
   GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
   GPIO_Config(GPIOA, &GPIO_ConfigStruct);
 
   USART_ConfigStruct.baudRate = 115200;
   USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
   USART_ConfigStruct.mode = USART_MODE_TX;
   USART_ConfigStruct.parity = USART_PARITY_NONE;
   USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
   USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
   USART_Config(USART1, &USART_ConfigStruct);
 
   USART_Enable(USART1);
while(USART_ReadStatusFlag(USART1, USART_FLAG_TXC)== RESET);  
 
     USART_TxData(USART1,'1');  
#ifdef TEST_TXC
     while(USART_ReadStatusFlag(USART1,USART_FLAG_TXBE) == RESET);
#endif
 
#ifdef TEST_TXBE
     while(USART_ReadStatusFlag(USART1,USART_FLAG_TXC) == RESET);  
#endif
     GPIO_SetBit(GPIOC,GPIO_PIN_0);__NOP();__NOP();__NOP();
GPIO_ResetBit(GPIOC,GPIO_PIN_0);__NOP();__NOP();__NOP();
 
     USART_TxData(USART1,'2');  
#ifdef TEST_TXC
     while(USART_ReadStatusFlag(USART1,USART_FLAG_TXBE) == RESET);
#endif
 
#ifdef TEST_TXBE
     while(USART_ReadStatusFlag(USART1,USART_FLAG_TXC) == RESET);  
#endif   
     GPIO_SetBit(GPIOC,GPIO_PIN_0);__NOP();__NOP();__NOP();
GPIO_ResetBit(GPIOC,GPIO_PIN_0);__NOP();__NOP();__NOP();
 
     USART_TxData(USART1,'3');  
#ifdef TEST_TXC
     while(USART_ReadStatusFlag(USART1,USART_FLAG_TXBE) == RESET);
#endif
 
#ifdef TEST_TXBE
     while(USART_ReadStatusFlag(USART1,USART_FLAG_TXC) == RESET);  
#endif   
     GPIO_SetBit(GPIOC,GPIO_PIN_0);__NOP();__NOP();__NOP();
GPIO_ResetBit(GPIOC,GPIO_PIN_0);__NOP();__NOP();__NOP();
 
PMU_EnterSTOPMode(PMU_REGULATOR_ON,PMU_STOP_ENTRY_WFI);
     while(1);
}

5 应用注意点总结
在轮询发送数据的方式下:
(1)要想发送的数据连续、中间无间隔,可以使用TXBE;
(2)在发送完最后1个字节、使用TXC时,可确保最后1个字节数据发送完成