(嵌入式C)STM32重定向print到串口发送

实现printf重定向的方式有两种,第一种是使用宏定义,第二种是重定向fputc

STM32F103C8T6,STM32CubeMX

1、HAL库,宏定义实现

直接上代码,我直接在HAL生成的main.c里面添加如下代码

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "stdint.h"
/* USER CODE END Includes */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define printf1(...) HAL_UART_Transmit(	&huart1,\
										(uint8_t *)u_buf,\
										sprintf((char *)u_buf,__VA_ARGS__),\
										0xffff)
/* USER CODE END PD */

/* USER CODE BEGIN PV */
uint8_t u_buf[256];
/* USER CODE END PV */

解释:
__VA_ARGS__是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。参考:#、##、__VA_ARGS__和##__VA_ARGS__的作用

传入函数会先执行,所以sprintf会先被执行,将(...)中的参数值写入u_buf中,该函数的返回值为写入字符串的长度,刚刚好填充了HAL_UART_Transmit函数的两个参数。

注意:是printf1而不是printf,如需使用printf请看2

2、重定向fputc

在usart.c中添加代码,在Options for Target, Target, Code Generation, Use MicroLIB的Check Box要勾选上(一般默认是勾选的)
在这里插入图片描述
上代码(其中的注释是参考了另一篇文章的,等找到了再补上):

/* USER CODE BEGIN 1 */
#if 1
/* 冲定义fputc需要包含头文件stdio.h */
#include <stdio.h>

/* 告知连接器不从C库链接使用半主机的函数 */
#pragma import(__use_no_semihosting)

/* 定义 _sys_exit() 以避免使用半主机模式 */
void _sys_exit(int x)
{
    x = x;
}
/* 标准库需要的支持类型 */
struct __FILE
{
    int handle;
};
FILE __stdout;

int fputc(int ch, FILE *stream)
{
    /* 堵塞判断串口是否发送完成 */
    while((USART1->SR & 0X40) == 0);

    /* 串口发送完成,将该字符发送 */
    USART1->DR = (uint8_t) ch;
    return ch;
}
#endif

/* USER CODE END 1 */

在main函数中就可以直接使用printf("内容")来发送内容到串口了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值