一、实验设计效果
通过重定向C标准库的printf和scanf函数,实现串口的格式化输出;
调用MDK微库(MicroLib)的方法和调用标准库的方法。
二、硬件工作原理和原理图
我们使用的正点原子STM32F103RB NANO开发板上将USART1(引脚为PA9,PA10)接出
USART1并没有在PCB上连接在一起,需要通过跳线帽来连接一下。这里我们把 P5 的 RXD 和 TXD 用跳线帽与 PA9 和 PA10 连接起来。
信号传输:串口 —— 调试器 —— USB ——电脑
三、实验记录
完成 CubeMX初始化配置 → 生成初始化HAL库工程 →在keli中编写串口程序
1. 完成 CubeMX初始化配置
1.1 利用CubeMX完成HAL库工程模板和初始化:
通过选择芯片型号创建CubeMX工程
在弹出的对话框中输入开发板上的芯片型号,STM32F103RB
在右侧筛选栏中选择Tx型,即开发板上芯片所用的LQFP64型封装,双击建立工程
1.2 RCC模块引脚的配置
在弹出的工程配置对话框中的第一个引脚配置选项卡下,先完成RCC时钟模块引脚配置:
选择启用外部的高速和低速时钟源,HSE和LSE,配置为晶振连接;
配置完成后,对应时钟引脚变绿,同时旁边出现其将要配置模式的文字说明;
1.3 串口的配置
- 在侧边栏的通信外设中选择USART1
- 在串口下拉框出选择异步(Asynchronous),成功后可以看到对应的串口引脚RX(接收引脚),TX(发送引脚)变绿。
- 选择下方的Parameter Settings选项卡确认串口参数。设置波特率为115200,传输数据长度为8 Bit,无奇偶校验位,1个停止位,数据方向(Data Direction)为接收和发送(Receive and Transmit)
- 在NVIC Settings选项卡下,开启串口中断,如需调整中断优先级可在右侧修改
1.4 完成时钟配置:
我们前面启用了RCC时钟模块的外部时钟引脚,这里我们需要将外部时钟源配置为实际使用的频率;
查看手册可知:LSE为32.768KHz,HSE为8MHz;
点击上方的时钟配置选项卡,进入时钟配置界面;
前面启用了外部晶振源,这里检查修改HSE\LSE的频率,和实际一致;
在主频选择框中输入72MHz,然后按回车OK;
系统将自动将时钟源、时钟流向、PLL等配置好,以产生相应的主频;
1.5 创建生成工程
2、printf 和 fputc
对于 printf 函数相信大家都不陌生,第一个C语言程序就是使用 printf 函数在屏幕上的控制台打印出Hello World,之后使用 printf 函数输出各种类型的数据,使用格式控制输出各种长度的字符,甚至输出各种各样的图案。
除此之外,在程序出错的时候,懒得调试,直接简单粗暴的加个 printf 找bug,有时候也不失为一种有效的方法。
对于已经习惯的 printf 函数,你了解多少呢?
printf 定义在 <stdio.h> 头文件中,如下:
int printf(const char *format, ...);
printf 函数根据 format 字符串给出的格式打印输出到 stdout(标准输出)中,当然,printf 函数是不会一个字符一个字符去输出,它会调用更底层的 I/O 函数:fputc去逐个字符打印。
fputc 也定义于头文件 <stdio.h>中,如下:
int fputc(int ch, FILE *stream);
fputc 函数写入字符 ch 到给定输出流 stream,printf函数在调用该函数时,会向stream参数传入stdout从而打印数据到标准输出。
那么,要实现printf打印到串口就变得非常简单了,只需要重新定义fputc函数,在fputc的函数中将数据通过串口发送,称之为:fputc重定向或者printf重定向。
同理,只需要重新定义fputc函数,在scanf的函数中将数据通过串口接收,称之为:scanf重定向。
3. printf,scanf的重定向方法介绍
3.1 方法一 使用HAL库函数实现串口重定向(勾选Use MicroLib)
MicroLib是对标准C库进行了高度优化之后的库,供MDK默认使用,相比之下,MicroLIB的代码更少,资源占用更少,在MDK编译环境下可以使用其MicroLib,快速实现printf重定向;
1)勾选Use MicroLib,使用半主机模式
2)重定义fputc到串口
在MicroLib的stdio.h中,fputc()函数的原型为:int fputc(int ch, FILE* stream)
此函数原本是将 字符ch 打印到文件指针 stream 所指向的文件流去的,现在我们不需要打印到文件流,而是打印到串口1。
在 usart.c 中,重写 fputc 函数,利用HAL_UART_Transmit打印到串口1,相应的,fgets也可以HAL_UART_Receive重定向;
int fputc(int ch, FILE *f)
{
uint8_t temp = ch;
HAL_UART_Transmit(&huart1, &temp, 1, 0xffff);//huart1需要根据你的配置修改
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
别忘了在usart.h 中添加 stdio.h,这样在需要使用串口的文件中添加 usart.h 就可以使用串口HAL库和printf重定向了。
#include <stdio.h>
3.2 在MDK中使用标准库重定向printf
MicroLib很好,但在其他编译环境下不可用,有的MCU也不支持,这里再介绍使用标准库重定向printf,可以在各种编译环境下使用;
1)注意,不要勾选Use MicroLib使用半主机模式
2)重定向fputc()函数完整的代码
一样写在 usart.c文件中即可,这里使用了寄存器操作,运行效率更高;
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
FILE __stdin;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (uint8_t) ch;
return ch;
}
///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
uint8_t ch = 0;
while((USART1->SR&0X20)==0);//循环发送,直到发送完毕
ch = (uint8_t) USART1->DR;
return ch;
}
别忘了在usart.h 中添加 stdio.h,这样在需要使用串口的文件中添加 usart.h 就可以使用串口HAL库和printf重定向了。
#include <stdio.h>
在所给的例程中,我使用了条件编译 #ifdef USE_PRINT...#endif、#ifndef USE_MICROLIB... #else...#endif来裁剪和选择这部分功能,对于大段代码的启用/弃用也可使用 #if 0/1 ...#endif 来裁剪。
4. 编写main.c测试printf、scanf重定向
1)按前述方法,完成printf、scanf重定向
2)添加printf、scanf的测试程序
在main.c 中写一个简单的测试程序,测试printf和scanf的整数、浮点数、字符和字符串的格式化输入输出。
/* USER CODE BEGIN 2 */
uint8_t name[10];
int32_t age;
float score;
int8_t level;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
printf("Enter your name: \r\n");
scanf ("%10s",name);
printf("Enter your age: \r\n");
scanf ("%d",&age);
printf("Enter your score: \r\n");
scanf ("%f",&score);
printf("Enter your level: \r\n");
scanf ("%c",&level);
printf("\r\nHi, %s, %d years old. \r\n", name, age);
printf("Your score is %2.2f. Your level is %c.\r\n\r\n", score, level);
/* USER CODE END WHILE */
}
3)串口测试
a) 使用 XCOM 串口助手测试
打开串口助手,按下图提示进行测试,可以看到例程可以正常工作;
注意,烧录时最好要关闭串口,烧录完成后再重新打开;
每次烧录后,都要重新关闭/打开一次串口助手,串口助手XCOM 才能正常工作;
b) 使用远程串行终端软件 PuTTY 测试
PuTTY 是一个 Telnet/SSH/rlogin/ 纯 TCP 以及串行阜连线软件。常用于远程连接控制台调试,使用非常方便。这里我们串口的简单输入输出测试,也可以使用它。
①先进行终端设置,勾选输入的回显和换行,方便观察输入信息;
②点击串口,配置串口参数后即可打开;
文章来源:https://www.toymoban.com/news/detail-757250.html
③像控制台一样进行访问,可以回删修改输入,按回车键确认输入,使用非常方便;文章来源地址https://www.toymoban.com/news/detail-757250.html
到了这里,关于printf和scanf的串口重定向,格式化输入输出的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!