stm32_f103使⽤gcc编译的环境下printf打印函数的实现
前记
  gcc编译使⽤的printf打印函数需要的底层函数是和其他编译器不同的,以前的是⽆法使⽤的,这⾥有两种⽅法,⼀种是使⽤gcc库⾥⾯的printf函数,⾃⼰实现底层IO函数_write。另外⼀种⽅法是⾃⼰定义 printf函数,这⾥给出两者实现⽅法及测试结果。
⽅法⼀
 假如要使⽤gcc库⾥⾯的printf函数,这⾥使⽤底层编译函数是_read()和_write(). 这⾥的read和write函数需要在system.c⾃⼰实现的,具体的实现⽅法如下所⽰:
#include  <errno.h>
#include  <sys/unistd.h> // STDOUT_FILENO, STDERR_FILENO
int _write(int file, char *data, int len)
{
if ((file != STDOUT_FILENO) && (file != STDERR_FILENO))
{
errno = EBADF;
return -1;
}
// arbitrary timeout 1000
HAL_StatusTypeDef status =
HAL_UART_Transmit(&huart1, (uint8_t*)data, len, 1000);
// return # of bytes written - as best we can tell
return (status == HAL_OK ? len : 0);
}
⽅法⼆
 其实,说⽩了只要到串⼝写函数,还有另外⼀种巧妙的⽅法,就是⾃制printf函数,不使⽤库⾥⾯的,代码如下所⽰:
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
void vprint(const char *fmt, va_list argp)
{
char string[200];
if(0 < vsprintf(string,fmt,argp)) // build string
{
HAL_UART_Transmit(&huart1, (uint8_t*)string, strlen(string), 0xffffff); // send message via UART
}
}
void my_printf(const char *fmt, ...) // custom printf() function
{
va_list argp;
va_start(argp, fmt);
vprint(fmt, argp);
va_end(argp);
}
代码及运⾏结果
 在代码中,这⾥分别给出两种⽅法的运⾏结果,如下所⽰:
/
/ uart init
MX_DEBUG_USART_Init();
/* 锟⽄拷锟接帮拷锟⽄拷锟⽄拷始锟⽄拷 */
KEY_GPIO_Init();
printf("test is init !\n\r");
my_printf("test pressed my printf \n\r");
/* 锟⽄拷锟⽄拷循锟⽄拷 */
while (1)
{
if(KEY1_StateRead()==KEY_DOWN)
{
LED1_ON;
printf("key1 pressed!\n\r");
//my_printf("key1 pressed my printf \n\r"); }
if(KEY2_StateRead()==KEY_DOWN)
{
LED2_ON;
printf("key2 pressed!\n\r");
//my_printf("key2 pressed my printf \n\r"); }
if(KEY3_StateRead()==KEY_DOWN)
{
LED1_OFF;
LED2_OFF;
printf("key3 pressed!\n\r");
//my_printf("key3 pressed my printf \n\r"); }
}
运⾏结果:
printf函数是如何实现的
参考⽬录
  1
2