文章目录
发送串口数据偶尔丢失字节
场景: 在STM32单片机中进行串口数据发送,在Linux/Windows上进行串口数据接收,会偶发出现接收到的数据有某些字节丢失。
分析: 在STM32中可以使用printf
用于发送串口数据,该函数内部实际上调用了接口:
/*********************************************************************
* @fn fputc
* @brief Support Printf Function
* @param data - UART send Data.
* @return data - UART send Data.
*/
int fputc(int data, FILE *f)
{
#if (DEBUG == DEBUG_UART1)
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData(USART1, (u8) data);
#elif (DEBUG == DEBUG_UART2)
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
USART_SendData(USART2, (u8) data);
#elif (DEBUG == DEBUG_UART3)
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);
USART_SendData(USART3, (u8) data);
#endif
return data;
}
解决:
- 方案1:修改
fputc
内部实现
int fputc(int data, FILE *f)
{
#if (DEBUG == DEBUG_UART1)
USART_SendData(USART1, (u8) data);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
#elif (DEBUG == DEBUG_UART2)
USART_SendData(USART2, (u8) data);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
#elif (DEBUG == DEBUG_UART3)
USART_SendData(USART3, (u8) data);
while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
#endif
return data;
}
- 方案2:业务中不使用
printf
函数,使用自行实现接口
/**
* @brief 发送字节流到串口
* @param bytes 字节流数据
* @param length 字节流长度
*/
static void UART1_SendBytes(const uint8_t* bytes, uint32_t length)
{
uint32_t i;
for (i = 0; i < length; ++i)
{
USART_SendData(USART1, bytes[i]); /* CPU 将一个字节转入到 发送数据寄存器 */
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); /* 等待 发送数据寄存器 将该字节全部转入到 发送移位寄存器 */
}
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); /* 等待 发送移位寄存器 将数据帧的最后一个字节的最后一位发送出去,整个数据帧发送完毕 */
}