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的用法一样。

posted @   一叁五  阅读(89)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!
点击右上角即可分享
微信分享提示