STM32CubeIDE新建项目过程记录备忘(五)中断方式的USART串口通信 - 教程

我的野火开发板上有CH340串口芯片,CH340的RXD和TXD与STM32的PA9、PA10已经连接。

  • 定义GPIO管脚和设置串口参数

        在STM32CubeIDE新建项目过程记录备忘(一) 创建一个基础的模板-CSDN博客里面,我已经将PA9和PA10配置为USART1的TX和RX,并完成了串口参数的设置。

  • 设置中断

  • 编写代码

  • 生成代码

        黄齿轮生成代码。

        打开main.c,可以看到usart1的初始化函数,串口的参数全部在里面:

        以及,在stm32f1xx_it.c中的串口中断服务函数:

  • 引入必要的头文件

        在main.c中引入stdio.h和string.h

#include    /*比如printf()等常用函数在这里*/
#include   /*字符串处理*/
  • 设置缓冲区和完成标志

uint8_t rx_buffer[100]; // 接收缓冲区
uint8_t rx_data; // 接收数据变量
uint8_t tx_buffer[100]; // 发送缓冲区
volatile uint8_t rx_complete = 0; // 接收完成标志

  •  启动接收中断

  • 用一条字符串测试一下发送 

sprintf((char*)tx_buffer, "STM32 USART Communication Demo");  //将需要发送的字符格式化并写入字符数组(缓冲区)
HAL_UART_Transmit_IT(&huart1, tx_buffer, strlen((char*)tx_buffer));  //发送字符

仿真软件接收到了发送的字符串:

        这里注意:波特率之前设置的115200,不能正常通信,改成19200后正常,这在工程中很常见,如果不能正常通信就降低波特率试试。

  • 测试一下接收

在main.c的发送代码后加一条接收的代码:

发送和接收的这段完整代码: 

/* USER CODE BEGIN 2 */
// 启动第一个接收中断
HAL_UART_Receive_IT(&huart1, &rx_data, 1);
//发送一条字符串
sprintf((char*)tx_buffer, "STM32 USART Communication Demo");  //将需要发送的字符格式化并写入字符数组(缓冲区)
HAL_UART_Transmit_IT(&huart1, tx_buffer, strlen((char*)tx_buffer));  //使用中断发送字符
HAL_UART_Receive_IT(&huart1, rx_buffer, sizeof(rx_buffer));  //使用中断接收字符
/* USER CODE END 2 */

接收函数的解释: 

        当接收完成后,会调用HAL_UART_RxCpltCallback()这个回调函数,函数的原型在stm32f1xx_hal_uart.c内,看得出它是个弱定义函数,需要重新定义后才能使用。

重新定义的回调函数一般放在文件stm32f1xx_it.c内:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //usart接收中断回调函数
{
if(huart->Instance == USART1)
{
HAL_UART_Transmit_IT(&huart1,rx_buffer, sizeof(rx_buffer));   //将接收到的内容原样发送出去
HAL_UART_Receive_IT(&huart1, rx_buffer, sizeof(rx_buffer));  //使用中断接收字符
}
}

        看得出,在HAL_UART_RxCpltCallback()这个回调函数内又运行了一次接收指令:HAL_UART_Receive_IT(&huart1, rx_buffer, sizeof(rx_buffer)),目的是开启新的接收任务。

总结一下本例接收的过程:

        接收函数HAL_UART_Receive_IT()-->当接收到的数据达到预设字节数,产生中断,调用中断服务函数HAL_UART_RxCpltCallback()-->在中断服务函数内执行特定操作,本例的操作是将接收到的内容又发送出去,当然也可以是任何其他,比如计算、存储、操作GPIO等-->在中断服务函数内开启下一次接收任务。

需要注意的是:要外部声明一下接收缓冲区,不然会报错。

extern uint8_t rx_buffer[100];  //usart1接收缓冲区

 运行结果:

        在串口仿真软件XCOM中不停点击“发送”,每次发送一个字符串“abcdefghij”,当字符总数够100个后,stn32将接收到的100个字符发送给XCOM。

        当然了,在工程中,接收到的每帧数据不一定总是确定长度的,使用本例的代码就不能满足所有的场景需求,这就是下一篇的任务:接收不定长数据。

posted on 2025-08-04 17:08  ljbguanli  阅读(19)  评论(0)    收藏  举报