一個項目用到32下的多個串口,一般STM32C8T6型號擁有3個USART,串口的配置都很簡單,但是要使用的話就得解決他們之間的矛盾,
printf函數到底輸出在哪一個串口中?
先看這函數:
//重定義fputc函數,方便使用printf int fputc(int Data, FILE *f) { while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE)); //USART_GetFlagStatus:得到發送狀態位 //USART_FLAG_TXE:發送寄存器為空 1:為空;0:忙狀態 USART_SendData(USART1,Data); //發送一個字符 return Data; //返回一個值 }
在我們使用printf函數的時候,首先必須重定義fputc函數,在這個函數中,實現數據的發送,然后在 USART_SendData(USART1,Data); 中選擇需要的串口。一般是選擇串口1,所以這種情況下,
使用printf函數會打印到串口1。
那么我要用到串口2的printf函數該怎么辦呢 ?
配置什么的還是和串口1一樣,
1.配置usart2的串口配置,gpio,rcc enable。。。。
2.勾選usb micro lib,
3.添加頭文件#include <stdarg.h>,編寫USART2的printf函數:
void USART2_printf (char *fmt, ...) { char buffer[CMD_BUFFER_LEN+1]; // CMD_BUFFER_LEN長度自己定義吧 u8 i = 0; va_list arg_ptr; va_start(arg_ptr, fmt); vsnprintf(buffer, CMD_BUFFER_LEN+1, fmt, arg_ptr); while ((i < CMD_BUFFER_LEN) && buffer) { USART_SendData(USART2, (u8) buffer[i++]); while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); } va_end(arg_ptr); }
仔細看我們會發現,其實這個函數中包含了fputc,然后吧 USART_SendData(USART1,Data); 改為 USART_SendData(USART2,(u8)buffer[i++]); 循環通過串口2發送。
還有一種方法就是自己實現 printf的源碼(參考秉火程序):
/* * 函數名:USART2_printf * 描述 :格式化輸出,類似於C庫中的printf,但這里沒有用到C庫 * 輸入 :-USARTx 串口通道,這里只用到了串口2,即USART2 * -Data 要發送到串口的內容的指針 * -... 其他參數 * 輸出 :無 * 返回 :無 * 調用 :外部調用 * 典型應用USART2_printf( USART2, "\r\n this is a demo \r\n" ); * USART2_printf( USART2, "\r\n %d \r\n", i ); * USART2_printf( USART2, "\r\n %s \r\n", j ); */ void USART2_printf ( USART_TypeDef * USARTx, char * Data, ... ) { const char *s; int d; char buf[16]; va_list ap; va_start(ap, Data); while ( * Data != 0 ) // 判斷是否到達字符串結束符 { if ( * Data == 0x5c ) //'\' { switch ( *++Data ) { case 'r': //回車符 USART_SendData(USARTx, 0x0d); Data ++; break; case 'n': //換行符 USART_SendData(USARTx, 0x0a); Data ++; break; default: Data ++; break; } } else if ( * Data == '%') { // switch ( *++Data ) { case 's': //字符串 s = va_arg(ap, const char *); for ( ; *s; s++) { USART_SendData(USARTx,*s); while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET );//程序死在了這 } Data++; break; case 'd': //十進制 d = va_arg(ap, int); itoa(d, buf, 10); for (s = buf; *s; s++) { USART_SendData(USARTx,*s); while( USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET ); } Data++; break; default: Data++; break; } } else USART_SendData(USARTx, *Data++); while ( USART_GetFlagStatus ( USARTx, USART_FLAG_TXE ) == RESET ); } }
然后在這里面修改串口號就可以。
參考資料:https://blog.csdn.net/xzongyuan/article/details/28626163