在stdio.h中的printf 原本输出到控制台, 在单片机应用中一般将其改到串口, 并利用串口输出信息来调试程序,非常方便。(本文以USART1为例)
此外CubeMX及CubeIDE 由于自动生成基础代码,因此每当更改硬件配置的时候, 都会被重置生成的基础代码。 这里使用goto语句来避免部分修改过的基础代码被替换掉。
方法如下:
配置CubeMX ,选择芯片: 选择芯片后勾选右上角蓝色图标:"StartProject"
在系统内核中,配置系统时钟。在mode中, 选择使用外部晶振。
进入 Clock Configuration 进行时钟树的配置(根据外接晶振的实际情况配置)
进入Connectivity选项卡配置 串口, 这里使用USART1, Mode选择为A,,, 即异步通讯。
5.在该页的Configuration中,依次配置ParameterSettings, NVIC及GPIO
根据串口的情况, 配置波特率,数据长度,停止位,及校验位,如下图绿框
接着配置NVIC, 勾选打开 global Interrupt
最后配置GPIO选项, 引脚以及由系统自动生成了, 这里需要将引脚改为上拉模式,如下图
在projectManager中,选择编译环境,准备自动生成代码
最后一步, 生成代码
在生成的代码中,我们可以看到,基本外设的初始化等基础函数及框架都已经由CubeMX自己生成完毕,并能够直接使用了。
其中关于USART外设部分 主要由结构体UART_HandleTypeDef, 和相关外设初始化函数:
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);组成
这里为了方便维护,将printf重新定向做了一个.c文件和.h头文件。 并命名为uart_printf.c和uart_printf.h. 保存在UserSrc的文件夹中。打开选项卡, 对刚做的头文件路径进行添加。(否则即使在代码中添加了#include“uart_printf.h”也会找不到, 头文件必须添加搜索路径。)
同时在选项卡中勾选使用微库。 (否则, 无法使用微库, 也就是说, 你添加了stdio或者string这样的C语言标准库,也无法使用。)
接着在生成的代码中 添加头文件。 注意, 用户代码必须严格的写在USER CODE BEGIN和END之间, 否则容易被重置掉。
代码自动生成的相关外设,不用管。 如果printf使用的是USART1, 就将huart1的结构体删除, 因为我们把这个结构体的声明放在了uart_printf.h中
在main函数中使用goto语句跳过初始化, (其实也不是跳过初始化, 而是跳过系统自动生成的部分,使用用户代码部分中的初始化, 来避免更改配置后被重置的一些问题。 )
在下面USART初始化函数的位置添加 空闲中断函数
接着创建两个文件, uart_printf.h和uart_printf.c
/*************uart_printf.h*********************/
#ifndef _UART_PRINT_H
#define _UART_PRINT_H
#include "main.h"
#include "stdio.h"
#ifndef _UART_PRINT_C
//放置需要被外部调用的uart.c文件中的全局变量\函数
#endif
extern UART_HandleTypeDef huart1;
void Usart_SendString(uint8_t *str);
int fputc(int ch, FILE *f);
int fgetc(FILE *f);
#endif
uart_printf.c文件如下:
/*************Printf重定向UART**************/
/*用途:
*使用printf将打印内容通过串口发送。
*原理:
*将C语言库函数中的fputc 和fgetc函数重新定向到UART串口
*使用方法及注意事项:
*使用前,需要在main.c中添加头文件 "stdio.h""uart_printf.h" 如果是keil编译器,同时需要在选项卡中勾选“使用微库”
*
*默认使用USART1串口, 当需要使用其他串口的时候, 修改huart1 为目标串口,
*建议使用CubeMX生成的代码,这样直接修改huart1后面的标号即可直接使用
******************************************/
#define _UART_PRINTF_C
#include "uart_printf.h"
/***************** 发送字符串(重新定向) **********************/
void Usart_SendString(uint8_t *str)
{
unsigned int k=0;
do
{
HAL_UART_Transmit(&huart1,(uint8_t *)(str + k) ,1,1000);
k++;
} while(*(str + k)!='\0');
}
///重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
/* 发送一个字节数据到串口DEBUG_USART */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
return (ch);
}
///重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
int ch;
HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 1000);
return (ch);
}
编译一下,就可以使用printf函数输出串口了
例如在需要的地方 加上printf输出:文章来源:https://www.toymoban.com/news/detail-764901.html
当程序运行到这里的时候, 就会利用串口1输出调试打印信息文章来源地址https://www.toymoban.com/news/detail-764901.html
到了这里,关于STM32开发中printf利用重定向方法输出到串口(CubeMX 基于HAL库方法,带实际项目应用技巧 巧用goto语句)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!