關於STM32中printf函式的重定向問題
printf函式一般是列印到終端的,stm32晶片除錯中經常需要用到串列埠來列印除錯資訊,那能不能用串列埠實現類似windows的Console中的printf呢?
答案是肯定的,那就是printf函式的重定向。
使用KEIL5對stm32的printf函式進行重定向,有兩種方法:一種是使用微庫,另一種是不使用微庫。
方法1--使用微庫:
1、使用微庫,在KEIL5中點選options for target,在” Target標籤下有個Use MicroLIB---勾選,使用微庫。
2、在串列埠檔案中新增如下程式碼:
#include "stdio.h"
#ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE* f) #endif /* __GNUC__ */
#ifdef __cplusplus extern "C" { #endif //__cplusplus
PUTCHAR_PROTOTYPE
{ while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET) ; USART_SendData(USART2, (uint8_t)ch);
return (ch); }
#ifdef __cplusplus } #endif //__cplusplus
這裡的:USART_SendData(USART2, (unsigned char) ch);
while (!(USART2->SR & USART_FLAG_TXE));
就是往串列埠傳送一個位元組的程式碼,修改相應的串列埠號,初始化,就能使用printf了。
方法2--不使用微庫(那麼就要強調不使用半主機(no semihosting)模式)
1、使用微庫(平臺式keil-MDK),點選“魔術棒options for target,在” Target標籤下有個Use MicroLIB---取消勾選,不使用微庫。
2、在串列埠檔案中新增如下程式碼:
#ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE* f) #endif /* __GNUC__ */ #ifdef __cplusplus extern "C" { #endif //加入以下程式碼,支援printf函式,而不需要選擇use MicroLIB #pragma import(__use_no_semihosting) //定義_sys_exit()以避免使用半主機模式 void _sys_exit(int x) { x = x; } void _ttywrch(int x) { x = x; } //標準庫需要的支援函式 struct __FILE { int handle; }; FILE __stdout; //重定義fputc函式 PUTCHAR_PROTOTYPE { while((USART2->SR & 0X40) == 0);//迴圈傳送,知道傳送完畢 USART2->DR = (u8)ch; return ch; } #ifdef __cplusplus } #endif //__cplusplus
同樣的,修改相應的串列埠號,初始化,就能使用printf了。
如果編譯的時候出現FILE __stdout;編譯不過,可以開啟stdio.h檔案,將typedef struct __FILE FILE;
修改為
typedef struct __FILE { }FILE;
即可。