核心目标:掌握 UART 串口通信原理,用 HAL 库实现 “开发板→电脑” 数据发送(模拟传感器数据上报)、“电脑→开发板” 指令接收(控制 LED),结合定时器实现定时发送,巩固非阻塞逻辑 —— 串口是嵌入式调试、数据传输的 “必备技能”,后续传感器数据上传、上位机控制都依赖它。
一、串口通信原理:嵌入式的 “双向数据线”(30 分钟)
串口(UART/USART)是 STM32 与外部设备(电脑、传感器、蓝牙模块)通信的常用接口,核心是 “异步通信”(无需时钟线,仅用 Tx 发送线、Rx 接收线),简单可靠。
1. 核心概念(新手必懂)
- UART(通用异步收发传输器):STM32 的基础串口外设,支持双向通信;
- 波特率:通信速率(常用 9600、115200bps,即每秒传输 9600/115200 位),双方必须一致;
- 数据格式:默认 “8 位数据位 + 1 位停止位 + 无校验位”(嵌入式最常用,CubeIDE 默认配置);
- 引脚对应(STM32F103C8T6):USART1 的 Tx=PA9,Rx=PA10(需在 CubeIDE 中配置为串口功能)。
2. 嵌入式场景用途
- 调试:开发板通过串口向电脑发送调试信息(如传感器数据、程序运行状态);
- 数据传输:接收电脑指令(如 “点亮 LED”“开始采集”),或向电脑上传传感器数据;
- 外设交互:与蓝牙、WiFi 模块通信(如通过蓝牙将温度数据发送到手机)。
3. HAL 库串口核心函数(重点记)
- 阻塞发送:
HAL_UART_Transmit(&huart1, 数据缓冲区, 数据长度, 超时时间);(发送时 CPU 等待,适合简单场景); - 中断接收:
HAL_UART_Receive_IT(&huart1, 接收缓冲区, 接收长度);(接收时不阻塞 CPU,通过中断回调处理数据,推荐用); - 中断回调:
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);(接收完成后自动调用,处理接收到的指令)。
二、实操 1:开发板→电脑,发送温度数据(40 分钟)
目标:开发板模拟温度传感器采集,通过 USART1 向电脑串口助手发送 “原始数据 + 校准后温度”,每秒发送一次(用定时器定时,巩固非阻塞)。
步骤 1:CubeIDE 配置串口 + 定时器
- 新建工程 “UART_Send_Data”,选择 STM32F103C8T6;
- 配置串口(USART1):
- 左侧 “Connectivity→USART1”:Mode 选 “Asynchronous”(异步模式);
- 参数默认:波特率 9600bps、8 位数据位、1 位停止位、无校验位;
- 配置引脚:PA9 设为 “USART1_TX”,PA10 设为 “USART1_RX”;
- 配置定时器(TIM3,定时 1s,复用第六天的配置):
- 预分频器 7199、自动重载值 9999(1s 中断一次),使能 TIM3 中断;
- 生成初始化代码。
步骤 2:编写发送逻辑(全局变量 + 定时器中断 + 串口发送)
- 打开
main.c,定义全局变量(温度数据 + 发送缓冲区):c
/* USER CODE BEGIN 2 */ uint32_t timer_count = 0; // 定时器计数(1s一次) int temp_raw = 250; // 模拟温度原始数据 float temp_real = 0.0; // 校准后温度 uint8_t send_buf[50]; // 发送缓冲区(存储要发送的字符串) /* USER CODE END 2 */ - 启动定时器和串口(
main函数中):c
/* USER CODE BEGIN 2 */ HAL_TIM_Base_Start_IT(&htim3); // 启动TIM3定时中断 /* USER CODE END 2 */ - 定时器中断回调函数(1s 更新温度并发送):
c
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM3) { // 1. 更新温度数据(模拟采集,每次+1,范围250-270) temp_raw = (temp_raw >= 270) ? 250 : temp_raw + 1; temp_real = (temp_raw / 10.0) + 2; // 校准公式 // 2. 格式化发送数据(将数值转为字符串存入缓冲区) sprintf((char*)send_buf, "原始数据:%d,校准温度:%.1f℃\r\n", temp_raw, temp_real); // 3. 串口发送数据(USART1,缓冲区,数据长度,超时100ms) HAL_UART_Transmit(&huart1, send_buf, strlen((char*)send_buf), 100); } }
步骤 3:电脑端配置串口助手
- 用 USB-TTL 模块连接开发板与电脑(开发板 PA9→TTL Tx,PA10→TTL Rx,GND→GND);
- 打开串口助手(如 SecureCRT、SSCOM),配置:
- 波特率 9600、数据位 8、停止位 1、无校验位、无流控;
- 选择对应的 COM 口(设备管理器中查看),打开串口。
步骤 4:下载测试
程序下载后,串口助手会每秒收到一条数据:原始数据:250,校准温度:27.0℃,且原始数据逐次递增(模拟传感器实时采集)。
三、实操 2:电脑→开发板,指令控制 LED(50 分钟)
目标:电脑通过串口发送指令(“ON”→点亮 LED,“OFF”→熄灭 LED),开发板接收指令后执行操作,同时定时向电脑反馈 LED 状态(结合实操 1 的定时发送)。
步骤 1:重新配置工程(添加 LED 引脚)
- 新建工程 “UART_Control_LED”,配置 USART1(同实操 1)、TIM3(1s 定时);
- 配置 LED 引脚:PC13 设为 GPIO_Output(初始熄灭);
- 生成初始化代码。
步骤 2:编写接收逻辑(中断接收 + 指令解析)
- 定义全局变量(接收缓冲区 + LED 状态):
c
/* USER CODE BEGIN 2 */ uint32_t timer_count = 0; uint8_t recv_buf[10]; // 接收缓冲区(存储电脑发送的指令) uint8_t led_state = 0; // LED状态(0=熄灭,1=点亮) uint8_t send_buf[50]; // 发送缓冲区 /* USER CODE END 2 */ - 启动定时器、串口发送和中断接收(
main函数中):c
/* USER CODE BEGIN 2 */ HAL_TIM_Base_Start_IT(&htim3); // 启动定时 // 启动串口中断接收(接收3个字节,对应“ON\r”“OFF\r”,\r是回车符) HAL_UART_Receive_IT(&huart1, recv_buf, 3); /* USER CODE END 2 */ - 串口接收完成回调函数(解析指令):
c
/* 串口接收完成回调函数:接收3个字节后自动调用 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 解析指令(忽略大小写,电脑发送“ON”“OFF”或“on”“off”都有效) if (strcmp((char*)recv_buf, "ON\r") == 0 || strcmp((char*)recv_buf, "on\r") == 0) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // 点亮LED led_state = 1; } else if (strcmp((char*)recv_buf, "OFF\r") == 0 || strcmp((char*)recv_buf, "off\r") == 0) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // 熄灭LED led_state = 0; } else { // 指令错误,发送提示 sprintf((char*)send_buf, "指令错误!请发送ON或OFF\r\n"); HAL_UART_Transmit(&huart1, send_buf, strlen((char*)send_buf), 100); } // 重新开启中断接收(HAL库中断接收一次后会关闭,需手动重启) HAL_UART_Receive_IT(&huart1, recv_buf, 3); } } - 定时器中断回调(1s 反馈 LED 状态):
c
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM3) { // 发送LED状态 sprintf((char*)send_buf, "LED状态:%s(发送ON点亮,OFF熄灭)\r\n", led_state ? "点亮" : "熄灭"); HAL_UART_Transmit(&huart1, send_buf, strlen((char*)send_buf), 100); } }
步骤 3:测试双向通信
- 串口助手配置同实操 1,打开串口;
- 发送指令 “ON”(回车),开发板 LED 点亮,串口助手收到反馈:
LED状态:点亮(发送ON点亮,OFF熄灭); - 发送指令 “OFF”(回车),LED 熄灭,反馈:
LED状态:熄灭(发送ON点亮,OFF熄灭); - 发送其他指令(如 “ABC”),开发板反馈:
指令错误!请发送ON或OFF。
四、第七天必掌握的 3 个关键知识点(10 分钟自测)
- 串口通信核心参数:波特率(双方必须一致)、数据格式(8N1:8 位数据 + 1 位停止 + 无校验);
- HAL 库串口函数:
HAL_UART_Transmit(阻塞发送)、HAL_UART_Receive_IT(中断接收)、HAL_UART_RxCpltCallback(接收回调); - 中断接收注意:HAL 库中断接收一次后会关闭,需在回调函数中重新调用
HAL_UART_Receive_IT开启下一次接收。
STM32串口双向通信实战

1247

被折叠的 条评论
为什么被折叠?



