当前位置: 首页 > news >正文

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 <stdio.h>   /*比如printf()等常用函数在这里*/
#include <string.h>  /*字符串处理*/
  • 设置缓冲区和完成标志

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。

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

http://www.dtcms.com/a/311875.html

相关文章:

  • 浏览器的全局焦点事件
  • 内循环全部满足条件后,为true
  • 大型地面光伏电站开发建设流程
  • IO流-字节流
  • c++--模板--实例化
  • ARM处理器概述及对比
  • 2025熵密杯 -- 初始谜题 -- Reproducibility
  • 基于落霞归雁思维框架的应用与实践研究
  • 计数组合学7.11(RSK算法)
  • Android动画实现控件形状、大小逐渐过渡
  • 智能制造——解读CMMM评估手册【附全文阅读】
  • DyWA:用于可推广的非抓握操作的动态自适应世界动作模型
  • 硅基计划3.0 学习总结 伍 优先级队列排序初识
  • 【Vue3】Class绑定:从基础到高级的完整指南
  • Web前端实现银河粒子流动特效的3种技术方案对比与实践
  • 【完结篇】华为OpenStack架构学习9篇 连载—— 09 OpenStack编排管理【附全文阅读】
  • 深入 Go 底层原理(三):Goroutine 的调度策略
  • OSPF综合
  • VS Code高效开发指南:快捷键与配置优化详解
  • 深入 Go 底层原理(十二):map 的实现与哈希冲突
  • Mybatis学习之获取参数值(四)
  • 字符串(java不死)
  • c++之基础B(进制转换)(第三课)
  • 详解Python标准库之并发执行
  • AI Agent开发学习系列 - LangGraph(3): 有多个输入的Graph
  • C#多数据库批量执行脚本工具
  • OneCode3.0 核心表达式技术深度剖析:从架构设计到动态扩展
  • 波士顿咨询校招面试轮次及应对策略解析
  • 双机并联无功环流抑制虚拟阻抗VSG控制【simulink仿真模型实现】
  • OneCodeServer 架构深度解析:从组件设计到运行时机制