STM32中DMA接收数据
STM32中DMA接收数据
更多
在STM32中使用DMA接收数据是一种高效的方式,能显著降低CPU负载。以下是关键步骤和注意事项(以UART接收为例):
基本步骤
-
配置DMA通道
// CubeMX配置或手动初始化(以UART1_RX为例) DMA_HandleTypeDef hdma_usart1_rx; hdma_usart1_rx.Instance = DMA1_Channel5; // 根据数据手册选择通道 hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; // 外设→内存 hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; // 外设地址固定 hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; // 内存地址自增 hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; // 按字节接收 hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_rx.Init.Mode = DMA_NORMAL; // 普通模式(循环模式用CIRCULAR) hdma_usart1_rx.Init.Priority = DMA_PRIORITY_MEDIUM; HAL_DMA_Init(&hdma_usart1_rx); __HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx); // 关联UART和DMA -
配置外设(UART)
// 使能UART的DMA接收请求 SET_BIT(huart1.Instance->CR3, USART_CR3_DMAR); -
启动DMA接收
uint8_t rx_buffer[100]; HAL_UART_Receive_DMA(&huart1, rx_buffer, sizeof(rx_buffer)); -
处理接收完成中断
// 在stm32fXxx_it.c中重写中断回调 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 处理接收完成的数据:rx_buffer // 可选:重启DMA接收下一批数据 HAL_UART_Receive_DMA(&huart1, rx_buffer, sizeof(rx_buffer)); } }
高级用法
1. 循环模式(Circular Mode)
hdma_usart1_rx.Init.Mode = DMA_CIRCULAR; // 自动循环填充缓冲区
- 无需在中断中重启DMA
- 使用半传输/完成中断处理数据:
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) { // 处理前半部分数据(0~49字节) } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { // 处理后半部分数据(50~99字节) }
2. 双缓冲(Double Buffer)
uint8_t rx_buf1[50], rx_buf2[50];
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rx_buf1, 50); // 启动接收
- 在接收完成回调中切换缓冲区:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if(huart == &huart1) { // Size为实际接收字节数 if(rx_buf1_full) process(rx_buf2, Size); else process(rx_buf1, Size); // 重新提交另一缓冲区 HAL_UARTEx_ReceiveToIdle_DMA(huart, next_buf, 50); } }
关键注意事项
-
内存对齐
确保缓冲区地址符合DMA要求(通常4字节对齐),可使用:__ALIGNED(4) uint8_t buffer[100]; // 对齐到4字节 -
中断配置
启用DMA传输完成中断:HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn); -
错误处理
重写错误回调函数:void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) { if(huart->ErrorCode & HAL_UART_ERROR_DMA) { // DMA传输错误处理 } } -
数据一致性
使用DMA时,确保CPU访问数据前检查状态或使用内存屏障:__DSB(); // 数据同步屏障
调试技巧
- 检查DMA标志位:
__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TCx) - 监视DMA计数器:
__HAL_DMA_GET_COUNTER(hdma) - 使用IDLE中断检测帧结束(配合
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE))
通过合理配置DMA,可实现高速、低功耗的数据接收,适用于UART、SPI、I²C、ADC等场景。参考对应型号的《参考手册》中的DMA章节获取通道映射信息。
如何解决PWM使用的DMA通道与串口接收的DMA通道撞车问题
项目做到一半,碰到个尴尬问题:PWM使用的DMA通道与串口接收的DMA通道撞车了,咋办?考虑一下,决定放弃idle中断+
2022-02-16 11:35:02
stm32 发送完数据后 串口继续发送_STM32之串口DMA接收不定长数据
引言在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段
资料下载
欲望都市
2021-12-24 19:17:48
STM32 HAL CubeMX 串口IDLE接收空闲中断+DMA
方法:一种是 :IDLE 接收空闲中断+DMA一种是: IDLE 接收空闲中断+RXNE
资料下载
张龙祥
2021-12-20 19:39:04
stm32 HAL库实现UART的不定长数据DMA接收的方法
发送接收就显得十分必要了,因为串口中断每收到一个byte的数据就会发生中断,这样会非常的消耗单片机的资源。而DMA接受一帧
2022-01-20 08:07:21
7天热门专题
换一换
换一换
- 如何分清usb-c和type-c的区别
- 中国芯片现状怎样?芯片发展分析
- vga接口接线图及vga接口定义
- 芯片的工作原理是什么?
- 华为harmonyos是什么意思,看懂鸿蒙OS系统!
- 什么是蓝牙?它的主要作用是什么?
- ssd是什么意思
- 汽车电子包含哪些领域?
- TWS蓝牙耳机是什么意思?你真的了解吗
- 什么是单片机?有什么用?
- 升压电路图汇总解析
- plc的工作原理是什么?
- 再次免费公开一肖一吗
- 充电桩一般是如何收费的?有哪些收费标准?
- ADC是什么?高精度ADC是什么意思?
- dtmb信号覆盖城市查询
- EDA是什么?有什么作用?
- 中科院研发成功2nm光刻机
- 苹果手机哪几个支持无线充电的?
- type-c四根线接法图解
- 华为芯片为什么受制于美国?
- 怎样挑选路由器?
- 元宇宙概念股龙头一览
- 锂电池和铅酸电池哪个好?
- 如何进行编码器的正确接线?接线方法介绍
- 什么是场效应管?它的作用是什么?
- 虚短与虚断的概念介绍及区别
- 晶振的作用是什么?
- 大疆无人机的价格贵吗?大约在什么价位?
- amoled屏幕和oled区别
- 苹果nfc功能怎么复制门禁卡
- 单片机和嵌入式的区别是什么
- 复位电路的原理及作用
- BLDC电机技术分析
- dsp是什么意思?有什么作用?
- 苹果无线充电器怎么使用?
- iphone13promax电池容量是多少毫安
- 芯片的组成材料有什么
- 特斯拉充电桩充电是如何收费的?收费标准是什么?
- 直流电机驱动电路及原理图
- 传感器常见类型有哪些?
- 自举电路图
- 苹果笔记本macbookpro18款与19款区别
- 通讯隔离作用
- 新斯的指纹芯片供哪些客户
- 伺服电机是如何进行工作的?它的原理是什么?
- 无人机价钱多少?为什么说无人机烧钱?
- 以太网VPN技术概述
- 手机nfc功能打开好还是关闭好
- 十大公认音质好的无线蓝牙耳机