STM32F103C8T6,无需重定向,利用串口发送信息

配置串口部分网上教程太多了,不做复述。
利用这种方法的好处是,printf只能重定向一个串口。而这种方法可以针对不同串口写不同的函数,实现很多串口的发送数据。
可以用串口1传输日志信息,串口2传输调试信息。当不需要时,直接在相关函数里把串口发送代码注释掉就行了。

代码

H文件

#ifndef USART_PRINT_H_
#define USART_PRINT_H_

#include <stdarg.h>
#include <stdio.h>
#include "main.h"
#include "usart.h"

#define UART1_SEND_LEN 100 //建议不要大于UART1_SEND_LEN - 2个

void UART1_print(char *fmt, ...);

#endif
  • 这里的UART1_SEND_LEN是指最多可以写入的字符数。
  • 理论来说应当是UART1_SEND_LEN - 1,因为最后还需要一个字符串的结束符号。
  • 但是实际可以传UART1_SEND_LEN长度的字符,这里也就是100个。但是只有UART1_SEND_LEN - 2个是经过判断的,这里和C文件的实现有关。

C文件

#include "usart_print.h"

void UART1_print(char *fmt, ...) {
	char buffer[UART1_SEND_LEN];
	uint8_t i = 0;
	va_list arg_ptr;

	va_start(arg_ptr, fmt); // 初始化可变参数

	vsnprintf(buffer, (unsigned int) (UART1_SEND_LEN), fmt, arg_ptr); // 格式化的数据写入字符串

	for(i = 0; i < UART1_SEND_LEN - 1 && buffer[i] != '\0'; i++);

//	while (buffer[i] != '\0') {
//		i++;
//	};

	HAL_UART_Transmit(&huart1, (uint8_t*) buffer, i + 1, 1000);
	va_end(arg_ptr);
}

  • 这里利用for循环做了一个计算字符串长度的操作。
  • 因为i是从0开始计数,所以当buffer[i] != '\0'的条件不满足时,i比当前字符串的实际长度要少1(在传输时’\0’最好也传输过去,所以当判断到’\0’时,'\0’并不在字符串长度之内),所以在发送串口数据时要对i进行加一操作。
  • 而当i < UART1_SEND_LEN这个条件不满足时,也就是没有找到'\0',此时i等于UART1_SEND_LEN,再经过后面的加一,明显越界了。所以为了方便就在判断时对UART1_SEND_LEN进行减一操作。
  • 所以实际可以传输的字符串长度是UART1_SEND_LEN,但是需要注意的是只有UART1_SEND_LEN -2个字符是经过buffer[i] != '\0'判断的
  • 被注释的部分是没有越界保护的计算字符串长度的方式,如果传输的字符没有结束符,程序就会卡在这里报错。
  • uint8_t的最大数是255,所以如果想把UART1_SEND_LEN设置的大于255,就需要把uint8_t换成uint16_t或者uint32_t
  • 程序中只有for(i = 0; i < UART1_SEND_LEN - 1 && buffer[i] != '\0'; i++);HAL_UART_Transmit(&huart1, (uint8_t*) buffer, i + 1, 1000);这一部分代码是可以自己修改的,其他部分基本是固定的。

最后直接在程序里调用就行了,用法和printf的用法一样。

STM32F103C8T6是一款基于ARM Cortex-M3内核的微控制器,它是STMicroelectronics公司推出的一款低功耗、高性能的单片机。HAL(Hardware Abstraction Layer)是STMicroelectronics提供的一套软件库,用于简化STM32微控制器的开发过程。 串口重定向是指将标准输入输出函数(如printf和scanf)重定向串口进行数据的输入输出。在STM32F103C8T6上使用HAL库进行串口重定向的步骤如下: 1. 配置串口:首先需要配置串口的参数,包括波特率、数据位、停止位、校验位等。可以使用HAL库提供的函数进行配置,例如`HAL_UART_Init()`。 2. 重定向标准输入输出流:通过重定向标准输入输出流,可以使用标准输入输出函数(如printf和scanf)进行串口数据输入输出。可以使用HAL库提供的函数,例如`HAL_UART_Receive()`和`HAL_UART_Transmit()`。 3. 重写标准输入输出函数:为了实现串口重定向,需要重写标准输入输出函数。可以通过重写`_write()`和`_read()`函数来实现。在这些函数中,可以调用HAL库提供的函数进行数据发送和接收。 下面是一个示例代码,演示了如何使用HAL库进行串口重定向: ```c #include "stm32f1xx_hal.h" #include "stdio.h" UART_HandleTypeDef huart1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); int _write(int file, char *ptr, int len) { HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, HAL_MAX_DELAY); return len; } int _read(int file, char *ptr, int len) { HAL_UART_Receive(&huart1, (uint8_t *)ptr, len, HAL_MAX_DELAY); return len; } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); printf("Hello, World!\n"); while (1) { // 读取串口数据并处理 char data; scanf("%c", &data); // 处理数据... // 发送数据串口 printf("Received: %c\n", data); } } void SystemClock_Config(void) { // 系统时钟配置... } static void MX_GPIO_Init(void) { // GPIO初始化... } static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值