彻底搞清printf在STM32上的使用

彻底搞清printfSTM32上的使用

重定向printf

ARMCC版本(keil MDK)

下面这段代码,在实现串口发送一个字节的函数后,可以在勾不勾选”微库“的情况下都可以正常使用printf函数。__MICROLIB是勾选微库后会被定义的宏,因而可以通过条件编译的方式兼容。
对应文件要包含<stdio.h>头文件,否则会提示FILE无定义。

#if !defined(__MICROLIB)
#pragma import(__use_no_semihosting)
void _sys_exit(int x) //避免使用半主机模式
{
  x = x;
}
struct __FILE
{
  int handle;
};
FILE __stdout;
#endif

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif 
PUTCHAR_PROTOTYPE
{
  /* 实现串口发送一个字节数据的函数 */
  serial_write(&serial1, (uint8_t)ch); //发送一个自己的数据到串口
  return ch;
}

ARMGCC版本(GCC)

ARMGCC库对printf函数的实现和ARMCC对printf函数的实现底层是不一样的,因而重定向的底层实现也有区别。

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif 
PUTCHAR_PROTOTYPE
{
    /* 实现串口发送一个字节数据的函数 */
    serial_write(&serial1, (uint8_t)ch); //发送一个自己的数据到串口
    return ch;
}

int _write(int file, char *ptr, int len)
{
	int DataIdx;
	for(DataIdx = 0; DataIdx < len; DataIdx++)
	{
		__io_putchar(*ptr++);
	}
	return len;
}

注意:在使用gcc进行printf进行打印输出时要加\r\n\n参数,否则有可能打印不输出。

重写printf

如果在使用多个串口的过程中都想是想用printf函数可以通过下面的方式来实现,只不过就不要使用printf的函数名了。

/* 用于实现自己的printf函数的原型 */
#include <stdarg.h>
#include <string.h> 
#include <stdio.h>

void serial2_printf( const char * format, ... )
{
  char buffer[256];
  va_list args;
  va_start (args, format);
  vsprintf (buffer,format, args);
  //send_via_USART1 (buffer);
  uint8_t len = strlen((const char*)buffer);
  for(uint8_t i = 0; i < len; ++i)
  {
    /* 通过串口发送一个字节的数据 */
    serial_write(&serial2, (uint8_t)buffer[i]);
  }
  va_end (args);
}

GCC下printf打印浮点数

默认情况下为了减小编译后的代码大小,GCC是不支持打印%f的浮点数的。需要通过添加链接指令开启-u_printf_float,如在makefile中做如下修改便可以打印浮点数:

# printf float
USE_FLOAT_PTINT = -u_printf_float

# libraries
LIBS = -lc -lm -lnosys 
LIBDIR = 
LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections $(USE_FLOAT_PTINT)

注意:

  • 无论是重定向printf函数还是重写printf函数都需要增加-u_printf_float编译指令后才能打印浮点数
  • 在打开浮点数打印的指令后代码尺寸会比之前大 10KB左右,在flash较小的单片机上斟酌使用
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值