STM32自学历程:USART传输及printf重定向实现
首先感谢
感谢江科大老师的视频讲解!
为什么要重定向Printf函数?
如果直接想用Printf函数打印东西到电脑串口上,那就要对Printf进行重定向,因为Printf函数是默认打印东西到屏幕上,但是单片机没有屏幕,所以就要对Printf进行重定向。
操作流程
1.先点击魔术棒,然后勾选Use MicoLIB,这个就相当于是一个函数库。
2.编写重定向函数
重定向函数也是Printf函数的底层函数,Printf函数实现打印的原理就是通过fput函数一位一位的打印,只不过未重定向之前,fput函数是将值打印到屏幕上,重定向就是让fput函数一位一位的把数据打印到串口而已。代码如下,一般将Printf重定向函数放到USART函数里面,另外,还要加上头文件#include “stdio.h”,不然编译器不知道FILE是什么类型。
#include<stdio.h>
……
… …
……
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1,Byte);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}
//下面才是重定向函数,相当于是函数间的互相调用
int fputc(int ch,FILE *f)
{
Serial_SendByte(ch);//这里重定向的是USART1端口
return ch;
}
3.利用printf函数打印数据
比如下面这个函数,就实现了在串口上重复打印0-9。这个知识点掌握后,以后做项目就更加得心应手了,比如打印个温湿度、煤气浓度什么的。这真是一个宝。
4.以防万一
如果编译时报出警告,说未声明,则直接在USART封装函数的.h文件里面加上#include<stdio.h>,因为stdio.h函数里面有现成的Printf声明。这些都是些死步骤,记住就行了。
关于Sprintf函数
当然,上面的printf方法有个缺点,就是只能重定向1个串口,比如重定向USART1后,串口2、3就不能使用printf打印了。为了实现让每个串口都能够使用printf打印,这里就使用Sprintf。
在这里首先认识一下Sprintf函数,这个函数不是我们自己创的,而是官方已经创好的,包含在<sdtio.h>。它的用法是:
// 引入stdio.h头文件,用于输入输出
#include <stdio.h>
// 定义一个字符数组,用于存储格式化后的字符串
char buffer[100];
// 定义一个整数变量,用于存储一个数字
int num = 10;
// 使用sprintf函数,将数字按照十六进制的格式写入字符数组
sprintf(buffer, "The number in hexadecimal is: %x", num);
// 打印字符数组的内容
printf("%s", buffer);
// 输出结果为:The number in hexadecimal is: a
这个和Printf函数用法几乎一
致,就是多了一位数组位。Printf函数是将数据打印到屏幕上,而Sprintf函数是将函数打印到定义的数组里面。
当然,Sprintf函数也需要封装,因为这里要引入C语言的可变参数。但要添加头文件
#include "stdarg.h"
#include "stdarg.h"
……
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1,Byte);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
}……
void Serial_SendString(char *String)
{
uint16_t i;
for (i =0; String[i]!= '\0' ;i++)
{
Serial_SendByte(String[i]);
}
}……
void Seial_Printf(char *format,…)
{
char String[100];
va_list arg;
va_start(arg,format);
vsprintf(String,format,arg);
va_end(arg);
Serial_SendString(String);}
这个函数和printf函数用法也是一模一样,可以直接打印汉字,也可以直接打印可变参数。
当然大多数情况都是用的Printf。会printf函数就够用了,因为串口打印数据一般也只用一个USART就够了。
谢谢大家的支持!