以下是本人在学习过程中关于printf重定向的笔记,主要看的是江协的视频,需要看原视频的可以点击下方链接学习原视频:
[9-3] 串口发送&串口发送+接收_哔哩哔哩_bilibili
背景
在进行单片机学习或者在实际开发中,想要通过printf()函数将数据输出到串口中,就需要对printf()函数进行重定向。
方法1:
使用keil中的MicroLIB,在工程选项中勾上“Use MicroLIB”
修改fputc()函数,将其重定向到串口(假设使用USART1来打印内容)。(printf在打印的时候,实际是在调用底层函数fputc函数,所以重定向fputc,就可以实现将内容打印到串口)
int fputc(int ch, FILE *f)
{
USART_SendData(USART1, ch); //将字节数据写入数据寄存器,写入后USART自动生成时序波形
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //等待发送完成
return ch;
}
在main.c中包含头文件 #include <stdio.h>,使用printf("a = %d\r\n",123)就可以把内容123打印到串口1了。
方法2:
使用sprintf()把格式化字符输出到一个字符串,调用Serial_SendString()函数将string输出到串口USART1中。
char string[100];/*定义一个字符串数组:存放格式化字符串*/
sprintf(string, "a = %d\r\n", 123);/*将要打印的“123”存储到数组中*/
Serial_SendString(string);
void Serial_SendData(uint8_t data)
{
USART_SendData(USART1, data);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);/*等待USART发送寄存器为空*/
}
void Serial_SendString(char* String)
{
int i;
for(i = 0; String[i] != '\0'; i++)
{
USART_SendData(USART1, String[i]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);/*等待USART发送寄存器为空*/
}
}
方法3:
对方法2进行封装
#include <stdarg.h>
/****************************************************************
**@brief 对方法2进行封装
**@param format:用于接收格式化字符串
...:接收可变参数列表
**@return 无
*****************************************************************/
void Serial_Printf(char *format, ...)
{
char String[100]; //定义字符数组
va_list arg; //定义可变参数列表数据类型的变量arg
va_start(arg, format); //从format开始,接收参数列表到arg变量
vsprintf(String, format, arg); //使用vsprintf打印格式化字符串和参数列表到字符数组中
va_end(arg); //结束变量arg
Serial_SendString(String); //串口发送字符数组(字符串)
}
在main.c中调用Serial_Printf("a = %d\r\n", 123);就可以把123打印到串口1中了。
注意,不管是哪种方法,既然printf要重定向到串口中,那么就需要先对UASRT进行初始化配置,如果需要了解具体配置过程的,可以跳转到原视频查看。
以上,就是关于printf重定向的笔记。