编写嵌入式单片机程序时,使用printf打印日志查看程序运行状态是一种常用的方法,通常我们会编写fputc函数重定向printf通过某一串口打印日志。fputc函数的一种实现方法如下:
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到UART0 */
Uart_Send_Data(UART0, ch);
/* 等待发送完毕 */
while (Uart_GetStatus(UART0, UartTC) == FALSE);
Uart_Clear_Status(UART0, UartTC); //清状态位
return (ch);
}
这时需要注意while循环中的判断条件——等待TC标志置位,有的单片机串口数据发送完成但是TC位没有置位,这就会导致程序不能退出while循环,现象就是死机了。
一种解决方法是while循环中判断TC标志位改为Txe标志位,实现如下:
int fputc(int ch, FILE *f)
{
/* 等待发送Tx Buffer 空 */
while (Uart_GetStatus(UART0, UartTxe) == FALSE);
/* 发送一个字节数据到UART0 */
Uart_Send_Data(UART0, ch);
return (ch);
}
为了解决程序死在while循环中不能退出的问题,我们可以增加超时退出:
int fputc(int ch, FILE *f)
{
unsigned int t = 0;
/* 等待发送Tx Buffer 空 */
while (Uart_GetStatus(UART0, UartTxe) == FALSE)
{
t++;
if(t >= 10000) //取值根据串口波特率以及单片机主频决定
{
break;
}
}
/* 发送一个字节数据到UART0 */
Uart_Send_Data(UART0, ch);
return (ch);
}