使用VSCode+STM32CubeMX+STM32 VS Code Extension拓展开发stm32过程中遇到的串口printf问题

之前使用keil开发stm32,可以勾选MicroLib来使用printf函数从串口输出数据

int fputc(int ch,FILE *f)
{
	unsigned char temp = ch;
	HAL_UART_Transmit(&huart1,&temp,1,0xffff);
	return temp;
}

但是在CubeMX环境下,这个方法似乎失效了,程序编译可以直接通过,但是实际串口无任何输出

于是在网上找相关资料,有网友建议参考正点原子的改写例程,禁用半主机模式就可以了

//禁用半主机模式
pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};

FILE __stdout;
//定义_sys_exit()以避免使用半主机模式  
void _sys_exit(int x)
{
x = x;
}
void _ttywrch(int ch)
{
ch = ch;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}

但是这个方法在使用VSCode+STM32 VS Code Extension拓展的方式下失效,原因是此时CubeMX生成的gcc编译环境,不支持使用pragma import命令来禁用半主机模式,我使用的gcc标准库,在标准库下,可以使用_write代替fput函数以实现重定义串口输出功能。

在你的usart.c文件中引用#include <stdio.h>头文件和stm32f1xx_hal.h

在文件末尾用户沙箱环境中重定义_write函数

#include <stdio.h>
#include <stdlib.h>
#include "stm32f1xx_hal.h"

extern UART_HandleTypeDef huart1;

int _write(int file, char *ptr, int len) {
    int DataIdx;
    for (DataIdx = 0; DataIdx < len; DataIdx++) {
        HAL_UART_Transmit(&huart1, *ptr++, 1, HAL_MAX_DELAY);
    }
    return len;
}

经过测试可以实现printf函数的输出,但是这并没有结束,实测如果你需要输出小数还是不可以,所以我们还需要设置编译器。

由于vscode使用的gcc编译器,所以我们可以在cmake菜单里添加链接器选项来打开浮点数支持。

具体方法为在项目根目录下的CMakeLists.txt文件中添加 -u _printf_float 选项

# 设置链接器选项

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u _printf_float")

至此就可以愉快的使用printf函数在串口输出浮点数了。

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注