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

STM32USART+DMA实现不定长数据接收/发送

STM32USART+DMA实现不定长数据接收

  • CubeMX配置
  • 代码分享
  • 实践结果

这一期的内容是一篇代码分享,CubeMX配置介绍,关于基础的内容可以往期内容

  • 夜深人静学32系列11——串口通信
  • 夜深人静学32系列18——DMA+ADC单/多通道采集
  • STM32串口重定向/实现不定长数据接收

CubeMX配置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

其余部分配置这里不做介绍,这里只展示串口+DMA部分

代码分享

  1. main函数
/* USER CODE BEGIN PTD */uint8_t Usart1_Send_Buffer[] = "公主王子请点赞!!!\r\n";uint8_t Recv_Buff[BUFFER_SIZE];  //接收数据缓存volatile uint8_t Recv_Length;  //接收一帧数据的长度volatile uint8_t Recv_DndFlag; //一帧数据接收完成标志int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能串口空闲中断HAL_UART_Receive_DMA(&huart1,Recv_Buff,BUFFER_SIZE);  //开启DMA串口接收,最大接收长度为 BUFFER_SIZE/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){       //通过串口1使用DMA的方式发送数据
//      HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Usart1_Send_Buffer, sizeof(Usart1_Send_Buffer)); 
//    HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/* USER CODE END PTD */

在main函数定义的数据,需要在mian.h里面声明外部变量

#define BUFFER_SIZE 256
extern uint8_t Recv_Buff[BUFFER_SIZE];  //接收数据缓存
extern volatile uint8_t Recv_Length;  //接收一帧数据的长度
extern volatile uint8_t Recv_DndFlag; //一帧数据接收完成标志
  1. USART1_IRQHandler中断函数
void USART1_IRQHandler(void)    
{/* USER CODE BEGIN USART1_IRQn 0 *///注意要在USART1_IRQHandler函数内判断串口空闲中断idle的状态,而不是到串口接收完成回调函数里面,//由于接收长度的限制,所以大概率是不会接收完成的
//    uint32_t temp;if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))//idle标志被置位为1,则说明接收完成,串口处于空闲状态{ __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位HAL_UART_DMAStop(&huart1); //接收完成,关闭DMA串口接收   Recv_Length  =  BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); //总计数减去未传输的数据个数,得到已经接收的数据个数//__HAL_DMA_GET_COUNTER(&hdma_usart1_rx);用于获取本次DMA传输中为传输的数据个数。Recv_DndFlag  = 1;   // 接受完成标志位置1    HAL_UART_Transmit_DMA(&huart1, Recv_Buff, Recv_Length);Recv_Length = 0;//清除计数Recv_DndFlag = 0;//清除接收结束标志位 ,也可以在其他地方判断,执行相应步骤后清除。memset(Recv_Buff,0,Recv_Length);HAL_UART_Receive_DMA(&huart1, Recv_Buff, BUFFER_SIZE);//重新打开DMA接收,不然只能接收一次数据}/* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 *//* USER CODE END USART1_IRQn 1 */
}

USART1_IRQHandler中断函数在stm32f4xx_it.c文件中,代码实现原理具体如下:

  • 开启串口1的空闲中断
  • 开启DMA串口1的接收数据,接收数据长度为BUFFER_SIZE(需要确保BUFFER_SIZE >正常的数据长度)
  • 在数据的接收过程中,串口处于忙碌状态,当接收完成时,串口空闲,发送中断。
  • 判断是空闲中断标志位置位,读取未完成传输的数据,计算接收的数据长度
  • 将计算数据长度的发送会串口,检验数据正确性
  • 清空接收的数据,再次开启DMA接收,重复以上过程。

实践结果

发送数据

在这里插入图片描述

接收数据

在这里插入图片描述

相关文章:

  • Node.js 的 os 模块介绍
  • 【多传感器融合】BEVFusion: 激光雷达和视觉融合框架 NeurIPS 2022
  • TemplateHit中提取query和hit比对上序列索引的映射字典
  • 用户运营:如何搭建用户分析体系
  • Centos 7 在线安装(RPM) PostgreSQL 14 15 16
  • ChatGPT 使用入门
  • C++学习 --函数对象
  • AWS EC2 如何 使用 SSM会话管理器登陆
  • python——第十五天
  • boa服务器移植
  • 关闭vscode打开的本地服务器端口
  • Linux系统iptables扩展
  • Android系统分析
  • HarmonyOS(十)——@Styles装饰器和stateStyles(多态样式)双剑合并
  • QT linux下应用程序打包
  • co.js - 让异步代码同步化
  • Cookie 在前端中的实践
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • laravel with 查询列表限制条数
  • laravel5.5 视图共享数据
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • ng6--错误信息小结(持续更新)
  • session共享问题解决方案
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 试着探索高并发下的系统架构面貌
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • #QT(智能家居界面-界面切换)
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (一)Java算法:二分查找
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET NPOI导出Excel详解
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .NET 使用 XPath 来读写 XML 文件
  • /var/spool/postfix/maildrop 下有大量文件
  • @param注解什么意思_9000字,通俗易懂的讲解下Java注解
  • @RequestBody的使用
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname
  • [2013][note]通过石墨烯调谐用于开关、传感的动态可重构Fano超——
  • [2016.7 day.5] T2
  • [C# 网络编程系列]专题六:UDP编程
  • [C语言]一维数组二维数组的大小
  • [Godot] 3D拾取
  • [HackMyVM]靶场 VivifyTech