波特律动
课程中心/STM32基础教程/【UART 串口】命令点灯(中断)

【UART 串口】命令点灯(中断)

注意

CubeIDE:请按照 例程使用方法🔗 导入例程,否则下载的可能不是例程而是其他工程。

Keil:请使用 ArmCC V6 编译,否则可能会出现编译错误。点击此处查看切换编译器方法🔗

如何使用例程

1️⃣ 编译并下载程序到学习板

2️⃣ 使用配套TYPE-C数据线,将学习板连接到计算机

3️⃣ 打开 波特律动 串口助手 在线串口调试助手,点击“选择串口”,选择USB Single Serial

4️⃣ 发送任意数据,即可看到接收到的数据原样返回

例程讲解

下面介绍了如何自己实现该例程的功能

1、工程配置

  • 分配引脚:在Pinout&Configuration页面,将 PA6、PA7、PB0 配置为 GPIO_Output,并分别设置 User label 为 BLUE、GREEN、RED
    1、左键点击对应的引脚,选择 GPIO_Output;
    2、右键点击对应的引脚,选择 User label,分别输入 BLUE、GREEN、RED
  • 打开串口2外设:Pinout&Configuration -> Connectivity -> USART2,将Mode选择为Asynchronous
  • 使能串口中断:在 USART2 -> Configuration -> NVIC Settings 标签卡中,勾选 USART2 global interrupt 的 Enable

2、代码

  • 定义全局变量 rx_data 作为串口接收缓冲区。
C语言
1// 串口接收缓冲区
2uint8_t rx_data[2];
  • 在 main 函数中,使用 HAL_UART_Receive_IT 函数开启串口接收中断
    只需要开启一次,接收到数据后会自动进入中断函数
C语言
1// 开启串口中断接收
2HAL_UART_Receive_IT(&huart2, rx_data, 2);
  • 在串口中断函数 HAL_UART_RxCpltCallback 中,处理接收到的数据,并控制LED
    所有的串口接收和发送操作都在中断函数中进行,不会阻塞主程序
    因此,while 循环中可以自由的处理其他任务
C语言
1// 串口接收完成(收到2个字节)中断回调函数
2void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
3{
4if (huart->Instance == USART2)
5{
6 // 根据接收到的数据控制 LED
7 GPIO_PinState state = GPIO_PIN_SET;
8 if (rx_data[1] == '0')
9 {
10 state = GPIO_PIN_RESET;
11 }
12 if (rx_data[0] == 'R')
13 {
14 HAL_GPIO_WritePin(RED_GPIO_Port, RED_Pin, state);
15 }
16 else if (rx_data[0] == 'G')
17 {
18 HAL_GPIO_WritePin(GREEN_GPIO_Port, GREEN_Pin, state);
19 }
20 else if (rx_data[0] == 'B')
21 {
22 HAL_GPIO_WritePin(BLUE_GPIO_Port, BLUE_Pin, state);
23 }
24 // 将收到的数据返回(中断发送)
25 HAL_UART_Transmit_IT(&huart2, rx_data, 2);
26 // 重新开启中断接收
27 HAL_UART_Receive_IT(&huart2, rx_data, 2);
28}
29}

3、返回数据发生颠倒

例如发送 R1 返回却变成 1R

  • 原因:HAL_UART_Receive_IT 固定接收2字节。发送非2字节数据(如1或3字节)会使剩余字节留在缓冲区,下次读取时导致数据错乱。