標準庫函數的默認輸出設備是顯示器,要實現在串口或LCD輸出,必須重定義標準庫函數里調用的與輸出設備相關的函數.
例如:printf輸出到串口,需要將fputc里面的輸出指向串口(重定向),方法如下:
只要自己添加一個int fputc(int ch, FILE*f)函數,能夠輸出字符就可以了
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(intch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE*f)
#endif
PUTCHAR_PROTOTYPE
{
USART_SendData(USART1,(uint8_t) ch);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) ==RESET);
return ch;}
因printf()之類的函數,使用了半主機模式。使用標準庫會導致程序無法運行,以下是解決方法:方法1.使用微庫,因為使用微庫的話,不會使用半主機模式. 如果使用的是MDK,請在工程屬性的“Target“-》”Code Generation“中勾選”Use MicroLIB“這樣以后就可以使用printf,sprintf函數了 方法2.仍然使用標準庫,在主程序添加下面代碼:
FILE __stdout;
在獨立應用程序中,您不太可能支持半主機操作。 因此,必須確保您的應用程序中沒有鏈接 C庫半主機函數。
問題:STM32如何使用printf函數進行串口輸出。
解答:寄存器版的/庫函數版的
第一步,#inlcude "stdio.h"
第二步,在主函數文件中重寫fputc()和fgetc()函數,如下:
int fputc (intch,FILE*f)
{
while(!(USART1->SR & USART_FLAG_TXE));
USART1->DR =(ch & 0x1FF);
return (ch);}
int fgetc (FILE* f)
{
while (!(USART1->SR& USART_FLAG_RXNE));
return((int)(USART1->DR &0x1FF));
}
第三步,工程屬性中的Target項中的Code Generation 選擇 UseMicroLIB。 即可使用printf進行串口輸出。
庫函數版本的:
如果使用的是MDK,請在工程屬性的“Target“-》”CodeGeneration“中勾選”Use MicroLIB“ 進行如上設置后編譯一下,串口輸出正確的數據。
#ifndef __UART_INTERFACE_H
#define __UART_INTEFFACE_H
#include "stm32f10x_lib.h"
#include "stdio.h"
void UART_Init(unsigned long UART_baud);//波特率,如115200
int fputc(int ch, FILE *f); //fputc重定向
int fgetc(FILE *f); //fgetc重定向
#endif 下面是.C的部分內容,省去了初始化的部分,自己看著寫好了
int fputc(int ch, FILE *f)//重新定向到串口發送出去的數據
{
USART_SendData(USART1, (u8) ch);
while(!(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == SET))
{ }
returnch;
}
int fgetc(FILE *f) //重新定向到串口接收到的數據
{
while(!(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET))
{ }
return (USART_ReceiveData(USART1));}
注釋: fgetc 和 fgetc是c語言的標準函數(形參是標準的) FILE *f是文件指針,具備文件系統的操作系統有用。對于簡單的無文件系統的嵌入式系統無用。
|