【STM32】HAL库——串口DMA通信(三)
前期准备:
- STM32CubeMX
- STM32RCT6核心板
- IDE Keil(MDK-ARM)
关于DMA
1. 什么是DMA?
DMA(Direct Memory Access,直接存储器访问) 提供在外设与存储器、存储器和存储器、外设与外设之间的高速数据传输使用。它允许不同速度的硬件装置来沟通,而不需要依赖于CPU,在这个时间中,CPU对于内存的工作来说就无法使用。
这里的外设指的是spi、usart、iic、adc等基于APB1 、APB2或AHB时钟的外设,而这里的存储器包括自身的闪存(flash)或者内存(SRAM)以及外设的存储设备都可以作为访问地源或者目的。
2. DMA的意义
传感器A获取到了数据,我需要把获取到的数据交给传感器B使用,正常来说,需要CPU控制,把A获取到的数据赋给B。但如果使用DMA,我可以将A与B之间建立一个专门传输数据的通道,CPU无需介入,对于非常大的数据需要转移时,DMA无疑大大节省了CPU的资源
优点: 控制简单,它适用于数据传输率很高的设备进行成组传送。
缺点: 在DMA控制阶段,CPU无法访问内存,内存的效能没有充分发挥,相当一部分内存工作周期是空闲的。这是因为,外围设备传送两个数据之间的间隔一般总是大于内存存储周期,因此许多空闲的存储周期不能被CPU利用。
3. DMA的结构器
2个DMA控制器,DMA1有7个通道
DMA2有5个通道
1个通道同一时间只能进行一个,例如通道 1 的几个 DMA1 请求(ADC1、TIM2_CH3、TIM4_CH1),这几个是通过逻辑或到通道 1 的,这样我们在同一时间,就只能使用其中的一个。其他通道也是类似的
3. DMA的传输方式
- DMA_Mode_Normal(正常模式)
一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次 - DMA_Mode_Circular(循环传输模式)
当传输结束时,硬件自动会将传输数据量寄存器进行重装,进行下一轮的数据传输。 也就是多次传输模式
4. DMA及通道的优先级
优先级管理采用软件+硬件:
软件:每个通道的优先级可以在DMA_CCRx寄存器中设置,有4个等级
最高级>高级>中级>低级硬件:如果2个请求,它们的软件优先级相同,则较低编号的通道比较高编号的通道有较高的优先权。比如:如果软件优先级相同,通道2优先于通道4
在大容量产品和互联型产品中,DMA1控制器拥有高于DMA2控制器的优先级。
5. DMA中断
DMA的每个通道都有 3 个事件标志(DMA 半传输,DMA 传输完成和 DMA 传输出错),这 3 个事件标志逻辑或成为一个单独的中断请求
可以通过设置寄存器的不同位来打开这些中断
6.指针递增模式
外设和存储器指针在每次传输后可以自动向后递增或保持常量。当设置为增量模式时,下一个要传输的地址将是前一个地址加上增量值
STM32CubeMX部分
1.配置时钟
选择STM32F103RCTx系列芯片,配置时钟的同时会自动配置IO口引脚
将HCLK设置为最大频率72MHz
2.配置USART和DMA
配置USART,【STM32】HAL库 CubeMX例程三—串口中断通信(2)(附工程源码)文章有讲解过,这里就不再赘述
DMA Settings ——> Add
然后选择USART1_RX,接着同样步骤再把USART1_TX添加进来
- DMA Request(DMA请求): USART1_RX、USART1_TX
- Channel(通道): 通道5、通道4
- Dirction (DMA传输方向): Peripheral To Memory(外设到内存)、Memory To Peripheral(内存到外设 )
- Priority(优先级): 低、低
- Mode(模式): 正常、正常
- Increment Address(地址指针递增): 1.这里因我们是一直往固定外设地址&USART1发送数据,所以地址不递增 2.这里我们的场景是将内存中连续存储单元的数据发送到串口,毫无疑问内存地址是需要递增的
- Data Width(数据宽度): 字节、字节
USART1使能中断
3.工程生成
工程管理依旧是这几个选项,然后GENERATE CODE,STM32CubeMX部分完成
MDK 5部分
//DMA函数
· HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);串口DMA模式发送
· HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);串口DMA模式接收
· HAL_UART_DMAResume(&huart1); 恢复串口DMA
· HAL_UART_DMAPause(&huart1) 暂停串口DMA
· HAL_UART_DMAStop(&huart1); 结束串口DMA
1. DMA串口发送
在main.c中添加
/* USER CODE BEGIN Init */uint8_t Senbuff[] = "Q大帅のUART DMA Test Success ! \r\n"; /* USER CODE END Init */
在while里写入
while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Senbuff, sizeof(Senbuff));HAL_Delay(1000); }
编译下载时需要选择相对应的下载器,勾选以下
效果如图
2. IDLE接收(串口空闲中断接收)
当DMA串口接收开始后,DMA通道会不断的将发送来的数据转移到内存,那该如何判断串口接收是否完成从而及时关闭DMA通道?如何知道接收到数据的长度?答案便是使用串口空闲中断
思路流程:
- 开启串口DMA接收
- 串口收到数据,DMA不断传输数据到内存
- 一帧数据发送完毕,串口暂时空闲,触发串口空闲中断
- 在中断服务函数中,可以计算刚才收到了多少个字节的数据
- 存储接收到的数据,清除标志位,开始下一帧接收
在原有代码上更改
//在main.c定义3个全局变量
/* USER CODE BEGIN Includes */
uint8_t rx_buffer[100]; //接收数据的数组
volatile uint8_t rx_len = 0; //接收数据的长度
volatile uint8_t recv_end_flag = 0; //接收结束标志位
/* USER CODE END Includes */
/* USER CODE BEGIN 2 */
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //开启空闲中断
HAL_UART_Receive_DMA(&huart1,rx_buffer,100); //开启DMA接收中断/* USER CODE END 2 */
在stm32f1xx_it.c文件中
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 */uint8_t tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE状态if((tmp_flag != RESET))//判断接收是否结束{ // recv_end_flag = 1; //接收结束__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清楚标志位HAL_UART_DMAStop(&huart1); uint8_t temp=__HAL_DMA_GET_COUNTER(&hdma_usart1_rx); rx_len =100-temp; //计算数据长度HAL_UART_Transmit_DMA(&huart1, rx_buffer,rx_len);//发送数据HAL_UART_Receive_DMA(&huart1,rx_buffer,100);//开启DMA}/* USER CODE END USART1_IRQn 1 */
}
效果如图
本期工程文档——>Gitee
【STM32】HAL库——串口DMA通信(三)相关推荐
- STM32 HAL库 串口DMA接收不定长数据
STM32 HAL库 串口DMA接收不定长数据 整体思路:我是用的CUBEMX软件生成的工程,使能了两个串口,串口2用来接收不定长的数据,串口1用来发送串口2接收到的数据:串口2我找了一个UBLOX卫 ...
- STM32 HAL库 串口DMA(收发)和STM32串口中断接收(接收时间管理机制)+ESP8266 wifi模组通信问题
一.HAL库 串口 DMA+ESP8266模组通信问题 用STM32 HAL库串口的DMA发送和空闲中断接收处理数据,单片机发送AT指令给ESP8266 wifi模组问题:单片机连续几次给wifi模组 ...
- STM32 HAL库串口同时收发,接收卡死?
STM32 使用 HAL库串口同时收发,使用踩坑史 = =!......by 矜辰所致 目录 前言 一. HAL 库串口收发 1.1 串口发送 1.2 串口接收 1.2.1 标准库接收 1.2.1 H ...
- STM32 HAL库串口收发数据
STM32 HAL库串口收发数据 许多传感器的使用方法是:单片机给传感器发送一帧数据,然后传感器返回单片机一帧有用数据,所以串口的收发功能十分重要. STM32cubeMX的配置 时钟和下载方式就不讲 ...
- STM32CubeMX HAL库串口+DMA数据发送不定长度数据接收
参考资料:1.ST HAL库官网资料 2.https://blog.csdn.net/u014470361/article/details/79206352#comments 一.STM32CubeM ...
- STM32 hal库串口空闲中断最新用法
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.串口空闲中断是什么? 二.使用步骤 1.hal库空闲中断接收函数 2.使用方法 3.最终效果 实际效果 总结 前言 ...
- hal库串口dma卡死_STM32 HAL库 串口DMA发送完成中断
近期使用STM32驱动MAX3485进行485通信,发现STM32F103C8并不自带硬件485首发功能,需要软件上控制IO高低来驱动MAX3485进行485接收.485发送. 根据MAX3485手册 ...
- hal库串口dma卡死_HAL库版DMA循环模式串口数据收发
在<STM32CubeMX初识与工程创建>的基础上,首先对串口进行设置,以实现通过串口对数据的收发.STM32CubeMX生成的HAL库中,提供了三类串口数据收发的接口,分别为阻塞模式,非 ...
- STM32 HAL库ADC+DMA(非定时器)代码和遇到的问题
目录 一.整体说明 二.部分知识点预览 三.代码部分 四.遇到的问题及现象 (1)仿真进入错误 (2)非连续模式软件触发时adcbuf里面的数据不对 (3)HAL库的ADC DMA相关中断的嵌套实现 ...
最新文章
- laravel5.6 数组传递到前端
- python开发的比较知名的游戏-游戏排行榜-Python实现
- JSP EL表达式 格式化日期
- EOJ_1017_座位分配
- 文本文档TXT每行开头结尾加内容批处理代码
- P4323-[JSOI2016]独特的树叶【换根dp,树哈希】
- 25--最后一个单词的长度
- 2017 年十大网页设计趋势
- bzoj 1078 [SCOI2008]斜堆 —— 斜堆
- Atitit prj tek dfkt 项目常见技术难点目录第一章 开发效率 2第一节 更加简单的语言 2第二节 简单
- 【回归预测】基于matlab离群鲁棒极限学习机(ORELM)求解回归预测问题【含Matlab源码 1441期】
- Vector原理与基本使用
- python机器学习 | 入门介绍
- 如何下载酷家乐的3D全景图效果图,并生成本地离线版vr全景漫游
- http://95u.free.fr/index.php,Electronic Software Distribution Service
- 数学建模国赛论文latex代码汇总
- 今夜酒店特价:订得早,不如订得好
- 【CodeForces】【状压DP】1155F-Delivery Oligopoly
- 常见的请求错误HTTP状态码
- 黑鹰的VIP数据库(一)
热门文章
- Redis从青铜到王者,从环境搭建到熟练使用,看这一篇就够了,超全整理详细解析,赶紧收藏吧
- 游戏陪玩平台源码开发中阿里云云存储OSS功能介绍
- android hmac加密,android hmacSha256 加密
- js报未定义_JS的未定义和undefined
- jsplumb应用场景快速开发
- 如何设置小型企业服务器机房
- mealy machine和moore machine
- linux中如何递归搜索文件,关于linux:递归查找具有特定扩展名的文件
- 数字货币如何影响货币体系_如何加入数字货币行业
- Excel(WPS部分功能不适用)技巧:快速找出重复值