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

HAL库配置RS485+DMA+空闲中断收发数据

前言:

(1)DMA是单片机集成在芯片内部的一个数据搬运工,它可以代替单片机对数据进行传输、存储,节约CPU资源。一般应用场景,ADC多通道采集,串口收发(频繁进入接收中断),SPI和IIC通信等

(2)STM32F2系列的DMA控制器最多有2个,每个控制器有8个数据流,每个数据流可以映射到不同的通道。例如,DMA2的数据流7可能用于某个特定外设,比如USART1的TX。(每个数据流同一时间只能服务一个外设。例如,若USART1_TX占用了DMA2_Stream7,则该流不可用于其他外设)

(3)DMA配置参数:

DMA请求源与通道选择:DMA1通道1

数据传输方向:外设 ↔ 存储器,存储器 ↔ 存储器

地址递增配置:外设地址递增和存储器地址递增(如果外设是ADC数据寄存器,关闭递增,如果存储器地址是接收数组,则开启递增)

数据宽度与对齐:外设/存储器数据宽度(串口一般是8位,ADC一般是16位)

传输模式:单次模式(串口接收)和循环模式(ADC采集数据)

正文:

1、配置时钟,烧入方式,配置RS485的接收使能脚

2、配置串口,DMA

3、串口串口收发缓存结构体

#define USART_TX_MAX_LEN 100
#define USART_RX_MAX_LEN 100
typedef struct
{unsigned char tx_buf[USART_TX_MAX_LEN]; unsigned char rx_buf[USART_RX_MAX_LEN];unsigned char rx_flag;unsigned char rx_len;
}usart_data_t;extern usart_data_t stUsart1Data;

 4、 串口初始化代码加入  开启IDLE中断、开始DMA接收

__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
HAL_UART_Receive_DMA(&huart1,stUsart1Data.rx_buf,USART_RX_MAX_LEN);

5、串口中断函数中加入 接收数据代码

void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 *//* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 */if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))  {__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位HAL_UART_AbortReceive(&huart1);	//已经接收完一帧数据,所以这里要停止接收,然后再重新接收	uint32_t   temp =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数 ,stUsart1Data.rx_len =  USART_RX_MAX_LEN - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数stUsart1Data.rx_flag = 1;	// 接受完成标志位置1	HAL_UART_Receive_DMA(&huart1,stUsart1Data.rx_buf,USART_RX_MAX_LEN);	//开始DMA接收}/* USER CODE END USART1_IRQn 1 */
}

6、配置串口printf打印函数

void Usart1Printf(const char *format,...)
{uint16_t len;va_list args;	va_start(args,format);len = vsnprintf((char*)stUsart1Data.tx_buf,sizeof(stUsart1Data.tx_buf)+1,(char*)format,args);va_end(args);if(HAL_UART_Transmit_DMA(&huart1, stUsart1Data.tx_buf, len)!= HAL_OK)   //判断是否发送正常,如果出现异常则进入异常中断函数{Error_Handler();}}

7、RS485通信加入使能发送和接收

/* USER CODE BEGIN 1 */
void USART1_RS485_Send_Enable(void)
{HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
}void USART1_RS485_Receive_Enable(void)
{HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);
}

8、测试代码

USART1_RS485_Receive_Enable(); //默认为接收使能while (1){/* USER CODE END WHILE */if(stUsart1Data.rx_flag  == 1)  //接收完成标志{USART1_RS485_Send_Enable();Usart1Printf("%s\r\n",stUsart1Data.rx_buf);HAL_Delay(100);//等待串口DMA发送完成,如果不加入此行代码,会出现发送失败,因为还没有发送完就切换成接收模式,导致不能发送数据 USART1_RS485_Receive_Enable();stUsart1Data.rx_len = 0;//清除计数stUsart1Data.rx_flag = 0;//清除接收结束标志位memset(stUsart1Data.rx_buf,0,USART_RX_MAX_LEN);}}

9、测试结果

10、优化RS485发送

当发送数据后,我们会等待一定时间,等待发送完成后在开启串口接收,但此时资源遭到了一定的浪费

优化思路:等待触发串口发送完成中断后,使能串口接收中断

void USART1_IRQHandler(void)
{HAL_UART_IRQHandler(&huart1);if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET))  {__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位HAL_UART_AbortReceive(&huart1);	//已经接收完一帧数据,所以这里要停止接收,然后再重新接收	uint32_t   temp =  __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);// 获取DMA中未传输的数据个数 ,stUsart1Data.rx_len =  USART_RX_MAX_LEN - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数stUsart1Data.rx_flag = 1;	// 接受完成标志位置1	HAL_UART_Receive_DMA(&huart1,stUsart1Data.rx_buf,USART_RX_MAX_LEN);	//开始DMA接收}if (HAL_UART_GetState(&huart1) == HAL_UART_STATE_READY) {// 发送完成 USART1_RS485_Receive_Enable();}
}USART1_RS485_Receive_Enable();while (1){/* USER CODE END WHILE */if(stUsart1Data.rx_flag  == 1)  //接收完成标志{USART1_RS485_Send_Enable();Usart1Printf("%s\r\n",stUsart1Data.rx_buf);
//		HAL_Delay(100);//等待串口DMA发送完成 
//		USART1_RS485_Receive_Enable();stUsart1Data.rx_len = 0;//清除计数stUsart1Data.rx_flag = 0;//清除接收结束标志位memset(stUsart1Data.rx_buf,0,USART_RX_MAX_LEN);}}

相关文章:

HAL库配置RS485+DMA+空闲中断收发数据

前言: (1)DMA是单片机集成在芯片内部的一个数据搬运工,它可以代替单片机对数据进行传输、存储,节约CPU资源。一般应用场景,ADC多通道采集,串口收发(频繁进入接收中断)&a…...

【java实现+4种变体完整例子】排序算法中【计数排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格

以下是计数排序的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格: 一、计数排序基础实现 原理 通过统计每个元素的出现次数,按顺序累加得到每个元素的最终位置,并填充到结果数组中。 代码示…...

嵌入式单片机开发 - Keil MDK 编译与烧录程序

Keil MDK 编译程序 1、Keil MDK 编译按钮 Build 按钮:重新编译整个工程的所有源文件,无论它们是否被修改过 Rebuild 按钮:仅编译修改过的文件及其依赖项,未修改的文件直接使用之前的编译结果 2、Keil MDK 编译结果 linking... …...

裂项法、分式分解法——复杂分式的拆解

目录 一、裂项法 1. 核心思想 2. 适用场景 3. 步骤 4. 例题 二、分式分解 1. 核心思想 2. 适用场景 3. 步骤 4.例题 一、裂项法 1. 核心思想 将一项拆解为多项之差,使得在求和时中间项相互抵消,最终仅剩首尾少数项。 2. 适用场景 级数求和…...

黑马点评秒杀优化

异步优化秒杀业务 回顾之前的内容黑马点评 秒杀优惠券集群下一人一单超卖问题-CSDN博客,为了处理并发情况下的线程安全和数据一致性的问题,我们已经完成了查询优惠券信息、判断秒杀是否开始和结束、检查库存、用户ID加锁、创建订单和扣减库存。 尽管之前…...

JavaScript 的演变:2023-2025 年的新特性解析

随着Web技术的飞速发展,ECMAScript(简称ES)作为JavaScript的语言标准,也在不断进化。 本文将带你学习 ECMAScript 2023-2025 的新特性。 一、ECMAScript 2023 新特性 1.1 数组的扩展 Array.prototype.findLast()/Array.protot…...

[Java · 初窥门径] Java 注释符

🌟 想系统化学习 Java 编程?看看这个:[编程基础] Java 学习手册 0x01:Java 注释符简介 在编写程序时,为了使代码易于理解,通常会为代码加一些注释。Java 注释就是用通俗易懂的语言对代码进行描述或解释&a…...

Spring MVC 全栈指南:RESTful 架构、核心注解与 JSON 实战解析

目录 RESTful API 设计规范Spring MVC 核心注解解析静态资源处理策略JSON 数据交互全解高频问题与最佳实践 一、RESTful API 设计规范 1.1 核心原则 原则说明示例 URI资源为中心URI 使用名词(复数形式)/users ✔️ /getUser ❌HTTP 方法语义化GET&…...

【web服务_负载均衡Nginx】三、Nginx 实践应用与高级配置技巧

一、Nginx 在 Web 服务器场景中的深度应用​ 1.1 静态网站部署与优化​ 在 CentOS 7 系统中,使用 Nginx 部署静态网站是最基础也最常见的应用场景。首先,准备网站文件,在/var/www/html目录下创建index.html文件: sudo mkdir -p…...

Docker环境下SpringBoot程序内存溢出(OOM)问题深度解析与实战调优

文章目录 一、问题背景与现象还原**1. 业务背景****2. 故障特征****3. 核心痛点****4. 解决目标** 二、核心矛盾点分析**1. JVM 与容器内存协同失效****2. 非堆内存泄漏****3. 容器内存分配策略缺陷** 三、系统性解决方案**1. Docker 容器配置**2. JVM参数优化(容器…...

【计算机网络】网络基础(协议,网络传输流程、Mac/IP地址 、端口号)

目录 1.协议简述2.网络分层结构2.1 软件分层2.2 网络分层为什么? 是什么?OSI七层模型TCP/IP五层(或四层)结构 3. 网络与操作系统之间的关系4.从语言角度理解协议5.网络如何传输局域网通信(同一网段) 不同网…...

【Mysql】mysql数据库占用空间查询

Mysql数据库操作 数据库大小查询 # 查询 每一个 数据库大小 SELECT table_schema AS 数据库名,SUM(data_length index_length) / 1024 / 1024 AS 数据库大小(MB) FROM information_schema.TABLES GROUP BY table_schema;# 查询 数据库占用磁盘大小 SELECT SUM(data_length …...

pgsql中使用jsonb的mybatis-plus和jps的配置

在pgsql中使用jsonb类型的数据时,实体对象要对其进行一些相关的配置,而mybatis和jpa中使用各不相同。 在项目中经常会结合 MyBatis-Plus 和 JPA 进行开发,MyBatis_plus对于操作数据更灵活,jpa可以自动建表,两者各取其…...

使用MetaGPT 创建智能体(2)多智能体

先给上个文章使用MetaGPT 创建智能体(1)入门打个补丁: 补丁1: MeteGTP中Role和Action的关联和区别?这是这两天再使用MetaGPT时候心中的疑问,这里做个记录 Role(角色)和 Action&…...

C# 使用.NET内置的 IObservable<T> 和 IObserver<T>-观察者模式

核心概念 IObservable<T> 表示 可观察的数据源&#xff08;如事件流、实时数据&#xff09;。 关键方法&#xff1a;Subscribe(IObserver<T> observer)&#xff0c;用于注册观察者。 IObserver<T> 表示 数据的接收者&#xff0c;响应数据变化。 三个核心…...

Redis——网络模型之IO讲解

目录 前言 1.用户空间和内核空间 1.2用户空间和内核空间的切换 1.3切换过程 2.阻塞IO 3.非阻塞IO 4.IO多路复用 4.1.IO多路复用过程 4.2.IO多路复用监听方式 4.3.IO多路复用-select 4.4.IO多路复用-poll 4.5.IO多路复用-epoll 4.6.select poll epoll总结 4.7.IO多…...

【dify实战】chatflow结合deepseek实现基于自然语言的数据库问答、Echarts可视化展示、Excel报表下载

dify结合deepseek实现基于自然语言的数据库问答、Echarts可视化展示、Excel报表下载 观看视频&#xff0c;您将学会 在dify下如何快速的构建一个chatflow&#xff0c;来完成数据分析工作&#xff1b;如何在AI的回复中展示可视化的图表&#xff1b;如何在AI 的回复中加入Excel报…...

vue3 传参 传入变量名

背景&#xff1a; 需求是&#xff1a;在vue框架中&#xff0c;接口传参我们需要穿“变量名”&#xff0c;而不是字符串 通俗点说法是&#xff1a;在网络接口请求的时候&#xff0c;要传属性名 效果展示&#xff1a; vue2核心代码&#xff1a; this[_keyParam] vue3核心代码&…...

裸金属服务器有什么用途?

裸金属服务器可以直接在硬件上运行应用程序和操作系统&#xff0c;不需要虚拟化层&#xff0c;裸金属服务器还会为企业提供一种高性能、高可靠性和高安全性的计算资源&#xff0c;通常运用在需要大量计算能力和数据处理能力的应用场景中&#xff0c;下面介绍一下裸金属服务器的…...

旅游特种兵迪士尼大作战:DeepSeek高精准路径优化

DeepSeek大模型高性能核心技术与多模态融合开发 - 商品搜索 - 京东 随着假期的脚步日渐临近&#xff0c;环球影城等备受瞩目的主题游乐场&#xff0c;已然成为大人与孩子们心中不可或缺的节日狂欢圣地。然而&#xff0c;随之而来的庞大客流&#xff0c;却总让无数游客在欢乐的…...

【MySQL】第一弹——MySQL数据库结构与操作

目录 一. 数据库介绍1.1 什么是数据库1.2 为什么要使用数据库1.3 主流数据库1.3.1 关系型数据库1.3.2 非关系型数据库 二. MySQL 的结构2.1 MySQL服务器和客户端2.2 MySQL服务器是如何组织数据的 三. 数据库的操作3.1 创建数据库语法格式示例 3.2 查看数据库语法格式示例 3.3 使…...

Spring_MVC 快速入门指南

Spring_MVC 快速入门指南 一、Spring_MVC 简介 1. 什么是 Spring_MVC&#xff1f; Spring_MVC 是 Spring 框架的一个模块&#xff0c;用于构建 Web 应用程序。它基于 MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;将应用程序分为模型&#xff08;M…...

L38.【LeetCode题解】四数之和(双指针思想) 从汇编角度分析报错原因

目录 1.题目 2.分析 去重的代码 错误代码 3.完整代码 提交结果 1.题目 四数之和 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元…...

字符串系列一>最长回文子串

目录 题目&#xff1a;解析&#xff1a;代码&#xff1a; 题目&#xff1a; 链接: link 解析&#xff1a; 代码&#xff1a; class Solution {public String longestPalindrome(String s) {char[] ss s.toCharArray();int n ss.length;int begin 0;//返回结果的起始字符串…...

双击热备方案及不同方案的需求、方案对比

双击热备方案概述 一般实现双机热备的方案有三种,分别是共享存储双机热备方案、镜像双机热备方案、双机双柜双机热备方案,这三种方案对硬件要求不同,大家可以根据自身的业务应用特性来选择具体的双机热备方案以及对应的ServHA双机热备软件产品。 1、镜像双机热备 1.1镜像…...

Antd中使用Form.List且有Select组件,过滤问题

当在使用Form.List组件&#xff0c;且组件中有Select选项时&#xff0c;针对每一次选择&#xff0c;都要过滤掉那些已经选择过的选项&#xff0c;可能遇到的问题&#xff1a; 直接过滤会将每一个Select中的options选项都过滤掉&#xff0c;无法正常展示选择的选项 解决办法&a…...

VSCODE插值表达式失效问题

GET https://cdn.jsdelivr.net/npm/vue2.6.14/dist/vue.js net::ERR_CONNECTION_-CSDN博客 更换正确的vue域名 GET https://cdn.jsdelivr.net/npm/vue2.6.14/dist/vue.js net::ERR_CONNECTION_ <script src"https://unpkg.com/vue2.6.14/dist/vue.js"></sc…...

【失败】Gnome将默认终端设置为 Kitty

起因 一会儿gnome-terminal一会儿kitty终端&#xff0c;实在是受不了&#xff0c;决定取缔默认的gnome-terminal。 过程 在 Ubuntu 或 Debian 系统上&#xff1a; 确保 Kitty 已经安装。如果未安装&#xff0c;可以在终端中运行命令sudo apt install kitty -y进行安装。 使用系…...

蓝桥杯:连连看

本题大意要我们在一个给定的nxm的矩形数组中找出符合条件的格子 条件如下&#xff1a; 1.数值相同 2.两个横坐标和纵坐标的差值相等&#xff08;由此可得是一个对角线上的格子&#xff09; 那么根据以上条件我们可以用HashMap来解决这个问题&#xff0c;统计对角线上数值相同…...

Ext系列⽂件系统

Ext系列⽂件系统 1. 理解硬件1.1 磁盘的物理结构1.2 磁盘的存储结构1.3 磁盘的逻辑结构理解过程实际过程 1.4 CHS&&LBA地址 2. 引入文件系统块分区innode 3. Ext2文件系统3.1 宏观认识3.2 block group3.3 块组内部3.3.1 GDT&#xff08;Group Descriptor Table&#xf…...