大致介紹
在使用usart2時,使用中斷傳輸進行printf會出現異常。使用阻塞傳輸無問題。在usart1中無問題。在GD32F407中無問題。直接使用中斷傳輸無問題。
使用代碼
正常配置串口,勾選microlib庫,重寫fputc
int fputc(int ch, FILE *f)
{
while(HAL_UART_Transmit_IT(&huart2, (unsigned char *)&ch, 1)!=HAL_OK){};
return ch;
}
結果
只配置usart2時,使用printf打印,只能接收到0x0C;

同時配置了usart1時,使用printf打印,只能接收到0x14;

同時配置usart3時,使用printf打印,只能接收到0x16;

同時配置usart6時,使用printf打印,只能接收到0x1e;

原因所在
在查詢串口相關的訊息時,考慮到不使用microlib庫打印會如何。
加入標准庫支持后,打印正常。
#pragma import(__use_no_semihosting)
//標准庫需要的支持函數
struct __FILE
{
int handle;
};
FILE __stdout;
/**
* @brief 定義_sys_exit()以避免使用半主機模式
* @param void
* @return void
*/
void _sys_exit(int x)
{
x = x;
}
同時發現,使用微庫時,優化等級也會造成影響。
在-o3,-o2,-o1時時,除了usart1以外,其他的均會出現以上情況。
-o0時,一切正常。(以上均是僅測試usart1,usart2,usart3)。
考慮到有在網上見到過:
選上Use MicroLIB,例如你用printf()函數的時候,就會從串口1輸出字符串,直接默認定向到串口1。
法1可實現串口1數據輸出,但要定向到串口2,串口3,microLIB就不合用了;
這樣的言論,也許有一定關系吧。
總結
此次問題的原因可以總結為microlib和優化等級共同造成的問題。在實際應用時,優化等級帶來的問題不容小覷;microlib作為缺省c庫,不符合iso c標准,也盡量不要使用。
參考文章:
關於在MDK中使用 printf 函數 - cronus象牙塔 - 博客園 (cnblogs.com)
微庫 & 斷言 & (Keil)代碼優化 | 靡不有初,鮮克有終 (shatang.github.io)
