HAL库串口重定向函数的编写和原理

目录

1.简介

2.传统方法

3.利用串口重定向功能实现printf函数


1.简介

在HAL库中我们想实现串口发送数据的功能时常用HAL_UART_Transmit() sprintf()这两个函数实现串口发送数据的功能,但在C语言中我们学习过printf这个函数,可以直接将所需要打印的数据打印在显示端,但由于在HAL库中是没有printf这个函数的,所以我们计划用重定向功能实现在HAL库中实现printf的功能

2.传统方法

进入HAL库先配置我们每次都要配置的高速时钟,选择我们的外部高速时钟

然后选择调试方式,选Serial Wire以便我们stlink的烧录

接下来配置我们的串口,选择串口一,模式选择异步通信,

然后选择波特率和接受位和检验位(对串口通信基本原理不懂的可以看我前面的文章),然后ctrl+s进入代码编写界面

进入代码编写界面后编写sprintf函数将我们需要发送的数值30 36存储到DTH11_BUF这个数组中(这个数组需要自行在上面定义),然后利用HAL_USART_Transmit()函数将存储在DTH11_BUF中的数据通过串口一发送出去,写好程序后将程序烧写到单片机里面去。

​
 while (1)
  {
    /* USER CODE END WHILE */

	      sprintf(DHT11_BUF,"H2:%2d T2:%2d \n",30,36);
	      HAL_UART_Transmit(&huart1,DHT11_BUF, strlen(DHT11_BUF), 1000);

	
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

我们打开串口调试工具(如果需要串口调试工具可以私信我发),先选择正确的串口号和与单片机相同的波特率校验位和数据位,而选择串口号的方式也很简单,插拔CH340看新增的串口号,新增的那个串口号就是我们设备对应的串口号,然后接受方式选择ASCII值,然后我们就会收到单片机发送的数据,我们可以看到的是单片机发送数据间隔很小,数据也是我们刚才写的,所以证明结合HAL_UART_Transmit()和 sprintf()可以实现单片机的数据发送,这是我们的传统方式,接下来我们介绍重定向后利用printf来代替HAL_UART_Transmit()和 sprintf()

要用重定向功能 ,那我们就要先明白重定向是上面意思,我们可以通俗的理解为,在HAL库中我们并没有printf这个函数,但我们又想用这个函数实现一定的功能,为了能使用这个函数,我们用一定的“手法”,在HAL中实现了Printf函数的功能

3.利用串口重定向功能实现printf函数

首先找到usart.c文件

然后在文件在文件的24行(也不一定在24行只要在BEGIN END对里面就可以了)定义一个数组,起名叫u_buf

然后右键#include "usart.h" 弹出框图后点击Open Declaration

然后就会跳转到“usart.h"文件中去,然后将下列代码写入.h文件中我用红色框框出来的地方,这样就可以实现我们的串口重定向功能了

extern uint8_t u_buf[256];
#define printf(...)  HAL_UART_Transmit(&huart1,(uint8_t *)u_buf, sprintf((char*)u_buf,__VA_ARGS__), 0xffff);

然后我们在主函数中写下printf函数

 while (1)
  {
    /* USER CODE END WHILE */
	  printf("H2:%2d T2:%2d \n"30,36);

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

然后我们继续烧录程序到单片机并打开串口调试软件,然后发现数据和我们使用传统方法得到的数据是一样的,这证明我们的重定向功能实现成功,我们成功的实现了printf函数的功能,和用printf函数代替了HAL_UART_Transmit() sprintf()这两个函数的功能。

至于那几句代码是什么意思,我只给出我的理解有可能不对,但初学者只要会用就好 如果想深入可以结合gpt一起学习

<think>好的,用户想了解关于串口重定向函数实现方法示例代码。根据提供的引用内容,我需要整理出具体的步骤代码示例。 首先,我需要理解什么是串口重定向串口重定向通常指的是将标准输出函数如printf的输出重定向串口,这样通过串口发送数据,方便调试。这在嵌入式开发中很常见,尤其是在使用微控制器如STM32或中颖51芯片时。 根据引用[2],中颖51芯片的实现需要重定向printf到串口,并提到了头文件引入代码配置。引用[3][4]提到STM32的实现需要重写_write函数或使用__io_putchar,并且必须包含stdio.h头文件。需要注意不同平台(如C51STM32)的实现方式可能不同,需要分别说明。 接下来,我需要整理不同平台的实现步骤。例如,在STM32CubeIDE中,用户需要在main.c中添加特定的代码,重定向_write函数__io_putchar函数。而在Keil C51中,可能需要修改putchar函数,并配置串口发送函数。 示例代码部分,需要分别给出STM32C51的代码片段,如引用[3]中的STM32代码引用[2]中的中颖51代码。同时,要指出关键点,比如包含头文件、实现特定函数、初始化串口等。 另外,用户可能遇到的问题,比如只实现部分函数导致不成功,或者未启用微(在STM32中),需要提醒这些注意事项。此外,引用[4]提到需要包含stdio.h,这也是一个关键点。 最后,生成的相关问题需要围绕串口重定向的应用场景、常见错误、优化方法等方面,帮助用户进一步了解。</think>### 串口重定向实现方法 #### 1. 核心原理 串口重定向通过重写标准中的输出函数(如`printf`),将其底层输出目标从默认终端改为串口设备。关键步骤包括: - 重定义`_write`函数(ARM平台)或`putchar`函数(C51平台) - 实现字符发送到串口的底层驱动 - 包含标准输入输出头文件`<stdio.h>`[^4] --- #### 2. 实现方式对比 | 平台 | 需重写函数 | 依赖配置 | 代码示例来源 | |-----------|---------------------|--------------------|---------------| | STM32 | `_write` + `__io_putchar` | 需启用`Use MicroLIB`[^3] | 引用[3][^3] | | C51 | `putchar` | 需自定义发送函数 | 引用[2][^2] | | 通用ARM | `_write` | 链接器配置 | 引用[4][^4] | --- #### 3. 具体实现示例 **STM32实现(HAL)** 在`main.c`中添加: ```c /* USER CODE BEGIN 0 */ #include <stdio.h> // 重定向基础输出函数 int __io_putchar(int ch) { HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 10); // huart1需替换为实际串口 return ch; } // 必须重写_write函数 int _write(int file, char *ptr, int len) { HAL_UART_Transmit(&huart1, (uint8_t*)ptr, len, 100); return len; } /* USER CODE END 0 */ ``` **C51实现(Keil)** 在串口驱动文件中: ```c #include <stdio.h> char putchar(char c) { EUART0_SendByte(c); // 调用芯片底层发送函数 return c; } ``` --- #### 4. 使用注意事项 1. STM32需在工程设置中启用`MicroLIB`[^3] 2. 必须保证串口已正确初始化 3. 多线程环境需添加互斥锁保护 4. 格式化输出会显著增加代码体积(C51需注意内存限制)[^2] ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值