STM32之HAL开发——DMA转运串口数据

DMA功能框图(F1系列)

如果外设要想通过 DMA 来传输数据,必须先给 DMA 控制器发送 DMA 请求, DMA 收到请求信号之后,控制器会给外设一个应答信号,当外设应答后且 DMA 控制器收到应答信号之后,就会启动 DMA 的传输,直到传输完毕

DMA映像表(F1系列)

DMA1通道请求映像

DMA2通道请求映像

注意:DMA 具有 12 个独立可编程的通道,其中 DMA1 有 7 个通道, DMA2 有 5 个通道,每个通道对应不同的外设的 DMA 请求。虽然每个通道可以接收多个外设的请求,但是同一时间只能接收一个,不能同时接收多个。

DMA_InitTypeDef 初始化结构体

arduino 复制代码
typedef struct {
uint32_t Direction; //传输方向
uint32_t PeriphInc; //外设递增
uint32_t MemInc; //存储器递增
uint32_t PeriphDataAlignment; //外设数据宽度
uint32_t MemDataAlignment; //存储器数据宽度
uint32_t Mode; //模式选择
uint32_t Priority; //优先级
} DMA_InitTypeDef;
  1. Direction:传输方向选择,可选外设到存储器、存储器到外设以及存储器到存储器。它设定DMA_SxCR 寄存器的 DIR[1:0] 位的值。 ADC 采集显然使用外设到存储器模式。
  2. PeripheralInc:如果配置为 DMA_PINC_ENABLE,使能外设地址自动递增功能,它设定DMA_CCR 寄存器的 PINC 位的值;一般外设都是只有一个数据寄存器,所以一般不会使能该位。
  3. MemoryInc:如果配置为 DMA_MINC_ENABLE,使能存储器地址自动递增功能,它设定DMA_CCR 寄存器的 MINC 位的值;我们自定义的存储区一般都是存放多个数据的,所以要使能存储器地址自动递增功能。
  4. PeriphDataAlignment:外设数据宽度,可选字节 (8 位)、半字 (16 位) 和字 (32 位),它设定DMA_SxCR 寄存器的 PSIZE[1:0] 位的值。 ADC 数据寄存器只有低 16 位数据有效,使用半字数据宽度。
  5. Mode: DMA 传输模式选择,可选一次传输或者循环传输,它设定 DMA_SxCR 寄存器的 CIRC位的值。我们希望 ADC 采集是持续循环进行的,所以使用循环传输模式。
  6. 软件设置数据流的优先级,有 4 个可选优先级分别为非常高、高、中和低,它设定 DMA_SxCR寄存器的 PL[1:0] 位的值。 DMA 优先级只有在多个 DMA 数据流同时使用时才有意义,这里我们设置为非常高优先级就可以了。

DMA存储器到外设实验

ini 复制代码
void Debug_USART_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
      
  __HAL_RCC_GPIOA_CLK_ENABLE();
  /* 使能 UART 时钟 */
  __HAL_RCC_USART1_CLK_ENABLE();  
   /* 配置Tx引脚为复用功能  */
  GPIO_InitStruct.Pin = DEBUG_USART_TX_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStruct);
  
  /* 配置Rx引脚为复用功能 */
  GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN;
    GPIO_InitStruct.Mode=GPIO_MODE_AF_INPUT;	//模式要设置为复用输入模式!	
  HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStruct);
  
  
  UartHandle.Instance          = DEBUG_USART;
  UartHandle.Init.BaudRate     = DEBUG_USART_BAUDRATE;
  UartHandle.Init.WordLength   = UART_WORDLENGTH_8B;
  UartHandle.Init.StopBits     = UART_STOPBITS_1;
  UartHandle.Init.Parity       = UART_PARITY_NONE;
  UartHandle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
  UartHandle.Init.Mode         = UART_MODE_TX_RX;
  
  HAL_UART_Init(&UartHandle); 
}

void USART_DMA_Config(void)
{
  DEBUG_USART_DMA_CLK_ENABLE();  
     
  DMA_Handle.Instance=DEBUG_USART_DMA_STREAM;                 //数据流选择
                             
  DMA_Handle.Init.Direction=DMA_MEMORY_TO_PERIPH;             //存储器到外设HAL_DMA_Init(&DMA_Handle);
  DMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式/* Associate the DMA handle */
  DMA_Handle.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式__HAL_LINKDMA(&UartHandle, hdmatx, DMA_Handle); 
  DMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;    //外设数据长度:8位
  DMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE;       //存储器数据长度:8位
  DMA_Handle.Init.Mode=DMA_NORMAL;                            //外设普通模式
  DMA_Handle.Init.Priority=DMA_PRIORITY_MEDIUM;               //中等优先级
  
  HAL_DMA_Init(&DMA_Handle);
  /* Associate the DMA handle */
  __HAL_LINKDMA(&UartHandle, hdmatx, DMA_Handle); 
  
}

  HAL_UART_Transmit_DMA(&UartHandle, (uint8_t *)SendBuff ,SENDBUFF_SIZE);

F4/F7系列DMA框图

在F4/F7系列中升级了FIFO功能,使得搬运的数据源和目标之间的存储器可以不用考虑数据大小一致问题,例如将一个字节的数据传输到一个字的存储器中去。FIFO在这之间起一个缓冲区的作用,可以将传输过来的数据,先攒一攒再一起发送。

H7系列DMA框图

在H7系列中新增了一个新的外设,DMAMyx(DMA请求中转调度器):建立DMA请求和DMA通道之间的映射关系,类似于路由的功能。无DMAMUX的MCU,DMA请求和DMA通道的映射关系是固定的,不能由软件修改。有了DMAMUX可以将DMA请求和DMA通道由软件联系起来,实现自定义链接。

复制代码
相关推荐
憧憬一下14 小时前
Pinctrl子系统中Pincontroller和client驱动程序的编写
arm开发·嵌入式·c/c++·linux驱动开发
蓝天居士14 小时前
ES8388 —— 带耳机放大器的低功耗立体声音频编解码器(4)
嵌入式·音频·es8388
田三番17 小时前
使用 vscode 简单配置 ESP32 连接 Wi-Fi 每日定时发送 HTTP 和 HTTPS 请求
单片机·物联网·http·https·嵌入式·esp32·sntp
启明智显21 小时前
AI笔筒操作说明及应用场景
人工智能·嵌入式硬件·嵌入式·ai大模型·启明智显·esp32-s3
FreakStudio1 天前
全网最适合入门的面向对象编程教程:58 Python字符串与序列化-序列化Web对象的定义与实现
python·单片机·嵌入式·面向对象·电子diy
Projectsauron5 天前
【STM32】通过 DWT 实现毫秒级延时
stm32·嵌入式·dwt
云中双月6 天前
如何使用Ida Pro和Core Dump文件定位崩溃位置(Linux下无调试符号的进程专享)
linux·嵌入式·gdb·调试·gcc·崩溃·ida pro·ulimit·core dump·cross compile
L_Z_J_I7 天前
超子物联网HAL库笔记:准备篇
笔记·物联网·嵌入式
飞凌嵌入式7 天前
FET113i-S核心板已支持RISC-V,打造国产化降本的更优解 -飞凌嵌入式
嵌入式硬件·嵌入式·risc-v·飞凌嵌入式
yufei-coder7 天前
使用语音模块的开发智能家居产品(使用雷龙LSYT201B 语音模块)
嵌入式·智能家居·语音模块