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

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.xdnf.cn/news/16922.html

相关文章:

  • 什么是需量跟随
  • 深入 Go 底层原理(八):sync 包的实现剖析
  • 动态规划经典模型:双数组问题的通用解决框架与实战
  • VirtualBox 的 HOST 键(主机键)是 右Ctrl 键(即键盘右侧的 Ctrl 键)笔记250802
  • 音视频学习(四十五):声音的产生
  • 图(遍历/最小生成树/单/多源最短路径)
  • Spring事务失效场景
  • Python 全局解释器锁
  • Web前端实现银河粒子流动特效的3种技术方案对比与实践
  • 使用C++实现日志(1)
  • 淘宝小程序的坑
  • 华为核心交换机S7700的内存OID
  • 阿里云:Ubuntu系统部署宝塔
  • JavaScript将String转为base64 笔记250802
  • Jotai:React轻量级原子化状态管理,告别重渲染困扰
  • Unity_数据持久化_XML基础
  • 计数组合学7.11(RSK算法)
  • 2024年网络安全预防
  • 仿muduo库实现高并发服务器
  • Python----大模型(基于LLaMA Factory角色扮演模型微调)
  • Kubernetes容器运行时-Docker or Containerd
  • 【最后一个单词的长度】
  • RK3399 启动流程 --从复位到系统加载
  • 双网卡UDP广播通信机制详解
  • Leetcode 11 java
  • fastGEO v1.7.0 大更新,支持PCA、差异分析、火山图、热图、差异箱线图、去批次等分析
  • uniapp 富文本rich-text 文本首行缩进和图片居中
  • Flutter开发 dart语言基本语法
  • 基于单片机一氧化碳CO检测/煤气防中毒检测报警系统
  • 深入理解 Docker 容器网络:为什么用 host 网络模式能解决连通性问题?