STM32 printf()函数和scanf()函数重定向到串口

学习STM32时,常需用串口测试代码,要用到printf()和scanf()函数,但它们默认不能输出到串口助手,需进行重定向。介绍了两个函数的底层函数接口及重定向函数的编写,还提醒使用时要包含头文件、勾选微型库,工程完成后可去掉。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#printf()函数和scanf()函数重定向
在学习STM32的时候,常常需要用串口来测试代码的正确与否,这时候就要要用到printf()函数或者scanf()函数,但是printf()这个函数是格式化输出到屏幕的,scanf()函数又是格式化输入(从屏幕),并不能输出到串口助手中,所以需要进行重定向。


在系统中有三个标准文件:标准输入,标准输出,标准错误。
***printf : 强大的格式化转换(可以将任何类型转为字符串)。 ***
scanf : 强大的格式化转换(可以将字符串类型转为任何类型)。


要重定向,首先要找到底层函数:
1.printf()函数的底层函数接口:在头文件<stdio.h>中第620行左右处,
这里写图片描述
找到这个函数后,就可以开始写函数了

int fputc(int c, FILE *stream)
{
	USART1->DR = c;//将c赋给串口1的DR寄存器,即重定向到串口,也可以是其他的接口
	while(!(USART1->SR & (1 << 7))){};//等待数据发送完成
	return c;
}

2.scanf()函数的底层函数接口:在头文件<stdio.h>中第595行左右处,
这里写图片描述
重定向函数如下:

int fgetc(FILE *stream)
{
	while(!(USART1->SR & (1 << 5))){};//等待数据接收完成
	return USART1->DR;
}

写好这两个函数后就可以在其他。.c文件中使用printf()函数将数据打印到串口调试助手了,当然也可以使用scanf()函数从串口调试助手输入数据。和C语言中的使用如出一辙,一毛一样!

值得注意的是:1.在头文件<stdio.h>中已经有fgetc()和fputc()这两个函数,为什么又可以再写这两个函数呢?难道不会产生重定义的错误吗?其实头文件<stdio.h>是在微信C语言库中,简称微型库。学过C语言的就知道,C代码在运行的时候,会优先在当前的.c文件中查找这两个函数,没有的话就会从系统默认的路径下查找。
使用printf()和scanf()时要包含头文件<stdio.h>,微型库也要勾选上,如下图:
这里写图片描述
2.勾选上微型库再进行编译的时候,会发现多了几KB的代码,在工程完成的时候就没必要再勾选上,再者,printf()函数仅仅是方便调试,在工程完成的时候也应该去掉!

您好,关于在STM32中使用scanf函数,需要先在代码中添加以下头文件: ```c #include <stdio.h> ``` 然后需要在初始化时使用以下代码: ```c void USART1_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; USART_InitTypeDef USART_InitStruct = {0}; /* Peripheral clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART1 interrupt Init */ HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); /* USART1 configuration */ USART_InitStruct.BaudRate = 115200; USART_InitStruct.WordLength = USART_WORDLENGTH_8B; USART_InitStruct.StopBits = USART_STOPBITS_1; USART_InitStruct.Parity = USART_PARITY_NONE; USART_InitStruct.Mode = USART_MODE_TX_RX; USART_InitStruct.CLKPolarity = USART_POLARITY_LOW; USART_InitStruct.CLKPhase = USART_PHASE_1EDGE; USART_InitStruct.CLKLastBit = USART_LASTBIT_DISABLE; HAL_USART_Init(&huart1, &USART_InitStruct); } ``` 其中,需要根据实际情况修改波特率引脚配置。然后在代码中使用scanf函数即可,例如: ```c int main(void) { char str[20]; USART1_Init(); while (1) { scanf("%s", str); printf("You input: %s\r\n", str); } } ``` 这样就可以通过串口输入数据并使用scanf函数读取了。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追代码的人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值