zaizai 直接储存器(DMA)是一种不经过CPU干预而直接在外设和存储器之间或者存储器和存储器直接的高速数据传输方式,从而提高CPU的利用率。
实现DMA数据传输有四个要素:
传输源:DMA数据传输的来源
传输目标:DMA传输的目的
传输数量:DMA传输数据的数量
触发信号:启动一次DMA数据传输的动作
DMA控制器概述
STM32-DMA:
两个 DMA 模块:DMA1 和 DMA2;
两个 DMA 控制器共有 12 个通道,每个通道专用于管理来自一个或多个外设的内存访 问请求。
每个控制器都有一个仲裁器,用于处理 DMA 请求之间的优先级; 支持外设到内存、内存到外设、内存到内存和外设到外设的数据传输; 每个通道都与来自外设的 DMA 请求信号或内存到内存传输中的软件触发器相关联。 此 配置由软件完成; 请求之间的优先级可由软件(每个通道 4 个级别:非常高、高、中、低)和硬件编程 (例如对通道 1 的请求优先于对通道 2 的请求)。
源和目标的传输大小是独立的(字节、半字、字),模拟打包和解包。 源地址和目标地 址必须在数据大小上对齐。 要传输的可编程数据数:0-65535;
STM32-DMAMUX:
DMA 请求多路复用器(DMA request multiplexer);
DMAMUX 请求多路复用器支持在外设和产品的 DMA 控制器之间路由 DMA 请求线。 路 由功能由可编程多通道 DMA 请求线多路复用器确保。 每个通道无条件地或与来自其 DMAMUX 同步输入的事件同步地选择唯一的 DMA 请求线。 DMAMUX 还可用作 DMA 请求生成 器,来自其输入触发信号上的可编程事件。
STM32-DMAMUX 特征:
多达 16 通道可编程 DMA 请求线多路复用器输出 4 通道 DMA 请求发生器;
21 个触发输入的 DMA 请求发成器; 21 个同步输入;
每个 DMA 请求线多路复用器通道输出:
来自外设的 115 条输入 DMA 请求线;
DMA方式的串口通信
采用中断方式进行串口通信时,每发送或接收一个字节都会产生中断,通知CPU进行处理。当通信速率较高(大于115200)时,大于每86us就会产生一次串口中断。导致其他任务无法及时完成。因此在实际工程如果通信速率较高使用DMA方式。
DMA方式的接口函数
1:串口DMA方式发送函数

2:串口DMA方式接收函数

3:DMA数据项数读取函数

4:串口DMA传输停止函数

挑战任务:
|
实验目的:
|
在采用轮询方式和中断方式进行数据的接收发时,HAL库只提供固定数据接收发的接口函数。然而在实际的工程应用中,往往需要不定长的数据接收发。
1:在STM32CubeMX软件中完成串口通信DMA的初始化设置
选择bit和芯片频率一样,我们使用F4,这里选择9600;

进行使能

2:代码书写:
实现功能函数:
void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart)
{
// 计算实际接收到的数据字节数
RecCount = 50 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
if (RecCount > 0) {
// 通过 DMA 发送接收到的数据
if (HAL_UART_Transmit_DMA(&huart1, (unsigned char *)RX, RecCount) != HAL_OK) {
// 处理发送错误
}
// 在 LCD 的第七行显示接收到的数据
LCD_DisplayStringLine(Line7, RX);
}
// 重置接收计数
RecCount = 0;
// 重新启动 DMA 接收
if (HAL_UART_Receive_DMA(&huart1, RX, 50) != HAL_OK) {
// 处理接收错误
}
}
在USART1_IRQHandler书写读取函数
if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清除 IDLE 状态标志
HAL_UART_DMAStop(&huart1); // 停�� UART 的 DMA 接收
HAL_UART_IdleCpltCallback(&huart1); // 调用用户定义的空闲完成回调函数
}
实验结果:


2万+

被折叠的 条评论
为什么被折叠?



