【嵌入式学习-STM32CubeMX篇】配置HAL库串口并重定向printf和getchar函数

为什么需要重定向printf和getchar函数

重定向printf和getchar函数可以将它们的输入/输出流重定向到其他设备或接口,最常见的情况是将它们重定向到串口。

这样做有以下几个主要原因:

  1. 调试和日志输出:通过重定向printf函数,可以将调试信息、状态和其他输出直接发送到串口。这对于调试嵌入式系统特别有用,因为通常无法直接在设备上查看输出。通过使用串口进行调试输出,可以实时监视系统状态、变量值和错误信息,从而更方便地进行调试和故障排查。

  2. 人机交互:通过重定向getchar函数,可以从串口接收用户输入,实现与嵌入式系统的交互。这使得用户可以通过串口终端或其他串口工具向系统发送命令、配置参数或提供输入数据。这对于需要与嵌入式系统进行交互的应用程序非常有用,例如控制台应用程序或配置工具。

  3. 引入标准库功能:重定向printf和getchar函数还可以在嵌入式系统中引入标准库(如C库)功能。标准库提供了许多有用的函数和工具,可以简化开发过程和代码编写。通过重定向这些函数,可以在嵌入式系统中使用标准库函数,如字符串处理、数学计算等,从而提高开发效率。

创建项目

选好你要的芯片型号
配置RCC

在这里插入图片描述

配置时钟树,配置时钟树,在Clock configuration中将HCLK频率设置为最高(看使用需求),等待软件自动改变时钟树的配置。
在这里插入图片描述

Debug选择 Serial Wire,右边的视图中出现了SWDIO和SWCLK两个引脚,这是用于SWD协议的仿真器和下载器的信号线。

在这里插入图片描述

在Connectivity 中选择 USART1 并在Mode中选择 asynchronous(异步),在最右边我们发现引脚A9、A10变成了USART1_TX(传输)和USART1_RX(接收)。

在这里插入图片描述

在NVIC Settings中有个USART1 global interrupt选项,你可以选择enabled也可以不选择

  在CubeMX中,USART1 global interrupt(全局中断)是指针对USART1串口模块的中断功能。中断是一种处理器与外部设备之间的通信方式,它允许设备在特定事件发生时中断处理器的正常执行流程,从而提高系统的响应性和效率。
  USART1是一种通用同步/异步收发器,用于串行通信。通过启用USART1 global interrupt,您可以在USART1接收到数据、发送完成或发生错误时,自动触发一个中断服务程序(ISR)。这意味着当某个事件发生时,处理器会立即停止当前的执行任务,转而执行中断服务程序来处理该事件。

在使用USART1进行串口通信时,启用USART1 global interrupt可以提供以下几个优势:

  1. 实时数据处理:当有数据到达USART1时,中断可以立即将控制权转移到中断服务程序,您可以在其中处理接收到的数据,进行实时的数据处理和响应。

  2. 节省处理器资源:使用中断处理数据和事件可以减轻处理器的负担。相比轮询方式,中断允许处理器在等待数据时进入低功耗模式或执行其他任务,而不需要不断检查串口接收状态。

  3. 提高系统响应速度:中断可以快速响应外部事件,使系统能够及时处理紧急情况或高优先级任务。这对于实时应用程序或需要快速响应外部设备的应用非常有用。

在CubeMX中启用USART1 global interrupt的具体步骤可能会因版本和配置而有所不同,但通常涉及到选择USART1外设,然后在中断配置选项中启用相关的中断标志。请注意,您还需要编写适当的中断服务程序来处理中断事件。

需要注意的是,启用中断会增加代码复杂性和处理器负担,因此在使用中断之前,您需要仔细考虑系统的需求和性能要求,确保正确配置和处理中断,以充分利用其优势。

在这里插入图片描述

在 Project Manager中更改IDE为MDK-ARM

在这里插入图片描述

勾选下图选项,方便程序解耦

在这里插入图片描述

点击generate code生成代码
在项目工程里面找到uart.c文件
添加代码块,重定向为串口一

// 重定向printf
int fputc(int ch, FILE *f){
	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);	
	return ch;
}

// 重定向getchar
int fgetc(FILE *f)
{
	int ch;
	while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) == RESET);
	HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
	return (ch);
}

在这里插入图片描述

在main.c里面写入测试代码

在这里插入图片描述
肯定有人会好奇,为什么重定向printf和getchar函数却是重写fputc和fgetc函数?

这是因为在C语言标准库中,printf和getchar等输入/输出函数实际上是依赖于更底层的字符输出函数fputc和字符输入函数fgetc来完成的。因此,通过重写fputc和fgetc函数,可以实现对printf和getchar函数的重定向。

  1. 统一接口:重写fputc和fgetc函数可以提供一个统一的接口,用于处理字符的输出和输入,而不仅仅局限于printf和getchar函数。这样,可以通过重定向这两个函数,同时重定向其他使用fputc和fgetc的函数,如puts、fgets等,实现整个输入/输出流的重定向。

  2. 更底层的操作:fputc和fgetc函数提供了对字符的更底层操作,可以直接与底层设备进行通信,如串口、文件系统等。重写这两个函数可以让我们将字符输出和输入重定向到所需的设备或接口,例如串口,从而实现定制的输入/输出流。

  3. 与C标准库兼容性:通过重写fputc和fgetc函数,可以保持与C标准库的兼容性。这意味着在重定向后,可以继续使用其他标准库函数,如sprintf、fprintf等,它们依赖于printf函数的输出。同样,可以使用其他标准库函数,如fgets、fscanf等,它们依赖于getchar函数的输入。

重写fputc和fgetc函数可以提供一个通用的底层接口,用于处理字符的输出和输入,并且与C标准库函数保持兼容。通过重定向这两个函数,可以实现对printf和getchar等高级函数的重定向,并且可以在更底层的级别上控制字符的输入和输出。这提供了更大的灵活性和定制化的能力,以满足特定嵌入式系统的需求。

build一下项目并download一下
通过串口助手观察结果

在这里插入图片描述

输入1,返回也是1 ,配置成功!

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值