之前使用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函数在串口输出浮点数了。