13 UART实验
串口数组和指针发送 串口中断接收
up的视频讲解: https://space.bilibili.com/1455872040
up视频里的实验代码: 👣串口实验代码
SerialPie串口助手测试例程: 📥串口助手测试代码
CH340驱动: 🔧CH340串口驱动安装
#include <stdio.h>
// printf输出重定向
int fputc(int ch, FILE *f)
{
uint8_t temp = ch;
HAL_UART_Transmit(&huart1, &temp, 1, HAL_MAX_DELAY);
return ch;
}
// scanf / getchar 输入重定向
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, HAL_MAX_DELAY);
return ch;
}
✉️ UART通信实验原理

微控制器是采用的是 UART通信 而电脑采用的是 USB通信
- UART与USB的物理连接 电平标准 以及数据帧的格式都存在区别
- 所以就需要CH340将UART通信协议与USB通信协议 进行转化
我们需要注意到一个本质的问题是 这些传输的 01数据到底代表着什么意思?

我们传的其实是 字符数据 什么是字符呢? 我们来看到这张ASCII表
- 如果计算机判定为是字符数据 那他就会拿到每一帧里的8bit数据
- 然后去这张ASCII表里面找到对应字符
- 比如说 字母A对应的就是0100 0001的数据 用十进制表示就是65
- 再比如说 这里的数字6 对应的就是0011 0110的数据 用十进制表示就是54
- 右边这一页 是
打印字符也就是具体可以在屏幕上显示的字符 - 而左边的这一页 是
非打印字符也就是做一些控制功能用的 比如说键盘上的回车 ESC返回
1 💻串口数组/指针发送实验
1.1 实验连接

1.2 实验原理

C语言中 Char 这个数据类型就代表着它存放的是一个字符 比如说这里的H 它本质上就是 将H对应的8位ASCII值写到RAM空间里面 但我们通常需要传输的是一串字符 比如说Hello 这时候我们就会用到 指针和数组这两种数据类型 来装这一串字符的ASCII值
数组
- 比如说用下面的数组的话 那么CPU就会将这5个字母的ASCII值 依次 存放到RAM里面
- 在结尾处还会加一个 \0表示字符串的结束
- 所以Hello这个字符串 一共花了6个字节的RAM空间去装
指针
- 而通过指针的方式 是这样Hello这里是一个常量数据 常量数据 在下载的时候就存放到flash里面的
- 它就不会像数组一个一个一个的拿到RAM里面 而是将第一个字符的地址 存放到RAM里面
- STM32是32位寻址 所以存的是32位也就是4个字节
- 数组名p代表着是第一个元素的地址
- 指针变量p的值也就是RAM里面存的地
址数据 而
*p这个*是一个寻址的指令

但up在这里还需要补充一点的是 在我们传数字的时候 往往传输的不是123这种常量数据 而是传输的像uinta float b这样的 变量
-
对于这些变量 我们在写程序的时候还不知道它里面装的是什么
-
这时候就需要调用到C语言的标准库的
Printf以及Sprintf函数 来帮我们将这些变量转化成字符
up简单说一下这两个函数的使用方法 在这个双引号里面的就是对应的字符内容 其中分为3部分
- 直接写上的 是
普通文本 - 百分号后面的 是
占位符就是帮后面的变量占位置 - \反斜杠后面的 是
转义符转义就是不是显示字符本身 而是其他意思
-
占位符百分号后面的字母也有区别 比如说变量a是uint8的类型就用%d占位 b是float浮点类型就用%f占位 -
转义符我们刚刚看到的ASCII表有打印和非打印两页 转义也就是将这个ASCII值对应非打印那一页 比如说这里的\r\n就是用于换行显示的意思

这两种方式 我们都可以使用
printf 默认是将转化后的字符输出到控制台显示的 所以需要 串口重定向 然后再通过uart发送
sprintf把格式化后的字符写入指针指向的缓冲区,并不会修改指针本身。实际项目优先用snprintf指定缓冲区容量,检查返回值后再发送
1.3 CubeMX配置
USART1选择Asynchronous,参数默认就好

1.4 实验代码
全局
#include <stdio.h>
main()
char p1[] = "Hello";
char* p2 = "world\r\n";
while(1)里面
HAL_UART_Transmit(&huart1,p1,sizeof(p1)-1,1000);
HAL_UART_Transmit(&huart1,p2,strlen(p2),1000);
printf("Hello World\r\n");
HAL_Delay(50);
2 📨串口中断接收实验
2.1 实验连接
在发送实验接线基础上补接CH340 TXD到PA10;PA9接CH340 RXD,GND共地。
2.2 实验原理
外设接满一个字节后触发回调,视频原代码重新开启接收,主循环根据rx判断。原例用于展示接收流程,不包含“消费后清除命令”的逻辑。
2.3 CubeMX配置
2.4 实验代码
全局
#include <stdio.h>
char rx = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Receive_IT(&huart1,&rx,1);
}
main()
HAL_UART_Receive_IT(&huart1,&rx,1);
while(1)里面
if(rx == '1')
{
printf("Hello World\r\n");
}
✅串口实验验收
先发送固定Hello,再让电脑发送字符1观察回应。视频原代码会在rx保持为字符1期间持续打印。若乱码,检查波特率、数据位、串口号、系统时钟与共地;若完全无数据,先看TX引脚波形。
字符串数组可以使用sizeof减去末尾零字符;指针变量的sizeof是指针大小,不是字符串长度。snprintf返回值达到或超过缓冲区容量表示截断,不应把这个返回值原样当作可发送长度。
中断接收例程是低速单槽演示。要处理持续输入,增加环形缓冲及溢出统计,并处理HAL_UART_ErrorCallback中的ORE等错误,再按所用HAL版本恢复接收。