關於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

修改相應的串口號,初始化,就能使用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

當然,頭文件#include "stdio.h"別忘了加上。同樣的,修改相應的串口號,初始化,就能使用printf了。

如果編譯的時候出現FILE __stdout;編譯不過,可以打開stdio.h文件,將typedef struct __FILE FILE; 

修改為

typedef struct __FILE
{

}FILE;

即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM