stm32之DMA

目录

  • 1.简介
  • 2.存储器映射
  • 3.DMA框图
  • 4.DMA基本结构图
  • 5.DMA请求
  • 6.数据宽度与对齐
  • 7.如何工作的
    • [7.1 数据转运+DMA](#7.1 数据转运+DMA)
    • [7.2 ADC扫描模式+DMA](#7.2 ADC扫描模式+DMA)
  • 8.结构体和相关api
    • [8.1 结构体](#8.1 结构体)
    • [8.2 api](#8.2 api)
        • [**1.** `void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx)`](#1. void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx))
        • [**2.** `void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)`](#2. void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct))
        • [**3.** `void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct)`](#3. void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct))
        • [**4.** `void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState)`](#4. void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState))
        • [**5.** `void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState)`](#5. void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState))
        • [**6.** `void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber)`](#6. void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber))
        • [**7.** `uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx)`](#7. uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx))
        • [**8.** `FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)`](#8. FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG))
        • [**9.** `void DMA_ClearFlag(uint32_t DMAy_FLAG)`](#9. void DMA_ClearFlag(uint32_t DMAy_FLAG))
        • [**10.** `ITStatus DMA_GetITStatus(uint32_t DMAy_IT)`](#10. ITStatus DMA_GetITStatus(uint32_t DMAy_IT))
        • [**11.** `void DMA_ClearITPendingBit(uint32_t DMAy_IT)`](#11. void DMA_ClearITPendingBit(uint32_t DMAy_IT))
  • 9.实验
    • [9.1 DMA转运](#9.1 DMA转运)
    • [9.2 DMA+AD多通道](#9.2 DMA+AD多通道)

1.简介

DMA(Direct Memory Access)直接存储器存取

DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源

12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道)

每个通道都支持软件触发和特定的硬件触发

STM32F103C8T6 DMA资源:DMA1(7个通道)

2.存储器映射

类型 起始地址 存储器 用途
ROM 0x0800 0000 程序存储器Flash 存储C语言编译后的程序代码
0x1FFF F000 系统存储器 存储BootLoader,用于串口下载
0x1FFF F800 选项字节 存储一些独立于程序代码的配置参数
ROM 0x2000 0000 运行内存SRAM 存储运行过程中的临时变量
0x4000 0000 外设寄存器 存储各个外设的配置参数
0xE000 0000 内核外设寄存器 存储内核各个外设的配置参数

对应到数据手册的

3.DMA框图


1. Cortex-M3 内核

  • 核心组件

    • Cortex-M3 是 STM32 的中央处理单元,负责指令执行和数据处理。
    • I-Code 和 D-Code:分别对应指令访问和数据访问的缓存接口,用于加速 Flash 和 SRAM 的访问。
    • 内核通过系统总线(System Bus)与外部资源(如 Flash、SRAM)交互。

2. 总线矩阵

总线矩阵(Bus Matrix)是 STM32 的通信枢纽,用于连接内核、外设、DMA 和存储资源。

  • 主要功能:协调系统中各模块之间的数据传输。

  • 连接模块

    • Flash:程序存储器。
    • SRAM:数据存储器。
    • RCC(复位与时钟控制):为系统提供时钟源。
    • AHB 从设备(如 DMA)。
    • APB1/APB2:挂载外设(如 UART、ADC、TIM 等)的子总线。

3. DMA 控制器

DMA(Direct Memory Access)用于实现 外设与存储器存储器之间 的数据直接传输,无需 CPU 干预,从而提高效率。

(1) DMA 控制器分类

图中显示了两个独立的 DMA 控制器:

  • DMA1 :提供 7 个通道,负责大多数外设数据的传输。
  • DMA2 :提供 5 个通道,支持额外的高带宽外设(如 SPI/I2S 和 USB OTG FS)。

(2) DMA 控制器内部结构

  • 通道(Channel)

    • 每个 DMA 控制器内部有多个通道,每个通道对应一个外设或传输任务。
    • 通道可以根据需求配置为 外设到内存内存到外设内存到内存 模式。
    • 每个通道都有专用的优先级设置和数据长度寄存器。
  • 仲裁器(Arbiter)

    • 控制 DMA 通道之间的资源分配,确保高优先级通道能够优先完成数据传输。
    • 仲裁器也可以分时分配总线,避免低优先级通道被完全堵塞。

(3) DMA 请求映射

DMA 控制器通过请求线与外设连接,用于启动传输。每个通道对应不同的外设请求源:

  • DMA1 请求

    • ADC1、ADC2(数据采集)。
    • USART1(串口通信)。
    • TIM1(定时器)。
    • GPIO(外部引脚)。
    • SPI1(串行外设接口)。
  • DMA2 请求

    • SPI2/I2S2 和 SPI3/I2S3(音频数据传输)。
    • USB OTG FS(数据传输)。
    • Ethernet MAC(以太网通信)。

(4) AHB 从设备

DMA 控制器通过 AHB(Advanced High-performance Bus) 从设备接口连接内存和外设。

  • 内存:SRAM。
  • 外设:如 ADC、SPI、USART 等。

4. 外设桥(APB1 和 APB2)

APB(Advanced Peripheral Bus)是挂载外设的低速总线,分为 APB1 和 APB2 两部分:

  • APB1(低速外设)

    • 包括定时器 TIM2TIM7、USART2USART5、I2C1、I2C2 等外设。
  • APB2(高速外设)

    • 包括 ADC1、ADC2、USART1、SPI1 等外设。

DMA 控制器可以从 APB1 或 APB2 请求数据传输。例如:

  • TIM2 的 DMA 请求通过 APB1 传递到 DMA1。
  • ADC1 的 DMA 请求通过 APB2 传递到 DMA1。

5. Flash 和 SRAM

  • Flash

    • 用于存储程序代码。
    • 内核通过指令缓存(I-Code)访问 Flash。
  • SRAM

    • 用于存储运行时数据。
    • DMA 可以直接访问 SRAM,实现外设与存储器之间的高效数据传输。

6. RCC(复位与时钟控制)

  • 作用:控制系统时钟信号,为 DMA、外设、总线等模块提供工作时钟。

  • 与 DMA 关系

    • DMA 控制器需要通过 RCC 配置时钟使能,才能正常工作。

4.DMA基本结构图

\1. 外设与存储器的配置

(1) 外设

  • 配置参数

    • 起始地址:指外设的寄存器地址,用于确定 DMA 从哪个外设读取数据。
    • 数据宽度:决定每次传输的数据大小,可以是 8 位、16 位或 32 位。
    • 地址是否自增 :决定在传输过程中,外设寄存器地址是否会随着数据传输而递增。通常外设地址固定,因此地址自增一般设置为 关闭

(2) 存储器

  • 配置参数

    • 起始地址:指数据存储的起始地址,可以是 SRAM 或 Flash 的地址。
    • 数据宽度:与外设匹配,决定每次传输的数据大小。
    • 地址是否自增:决定存储器地址在传输过程中是否递增。大多数情况下,存储器地址会递增以存储连续的数据。

\2. 数据传输方向

DMA 的数据传输有三种模式:

  • 外设到存储器

    • 例如:ADC 采样数据传输到 SRAM。
  • 存储器到外设

    • 例如:UART 发送数据从 SRAM 传输到外设寄存器。
  • 存储器到存储器(M2M)

    • 例如:从一段 SRAM 复制数据到另一段 SRAM。
    • 这种模式一般需要 DMA 支持特定的 M2M 功能。

方向的设置由 DMA 的控制寄存器决定,通常是用户根据传输需求手动配置。


\3. DMA 的触发方式

DMA 传输需要一个触发信号,触发方式有两种:

  • 硬件触发

    • 由外设生成的 DMA 请求信号触发,例如 ADC 采样完成后发出请求,启动 DMA 传输。
  • 软件触发

    • 通过编程手动触发 DMA 传输,用于内存到内存的复制等。

触发信号进入 DMA 后,DMA 控制器根据配置启动数据传输。


\4. DMA 的核心模块

(1) 外设寄存器

  • 作用:连接 DMA 与外设的接口。DMA 从外设寄存器读取数据或将数据写入外设寄存器。
  • 特点:通常是固定地址,不会递增。

(2) 传输计数器

  • 作用:记录需要传输的数据量。

  • 工作过程

    • 在每次完成一次数据传输后,传输计数器会减 1。
    • 当计数器减到 0 时,DMA 传输结束,触发中断或其他后续操作。
  • 配置方式:用户需要设置总的数据传输数量。

(3) 自动重装器

  • 作用:支持循环模式。

    • 在循环模式下,DMA 传输完成后,自动重装器会将初始配置重新加载到计数器,实现重复传输。
  • 用途:常用于持续采样的场景,例如 ADC 连续采样的数据传输。


\5. 数据传输路径

DMA 的数据传输涉及以下几个路径:

  • 外设到存储器:DMA 从外设寄存器读取数据,写入存储器(SRAM 或 Flash)。
  • 存储器到外设:DMA 从存储器中读取数据,写入外设寄存器。
  • 存储器到存储器:DMA 在内存之间直接传输数据,无需外设参与。

在传输过程中,数据宽度和地址的自增与否由配置决定:

  • 如果地址自增:

    • 存储器地址会递增,外设地址保持不变。
  • 如果地址固定:

    • 适用于外设地址(如 UART 或 ADC),只需操作同一个寄存器。

\6. 开关控制

  • DMA 传输的启停由用户手动控制或由硬件自动控制。

  • 开关控制寄存器的主要作用:

    • 启动或停止 DMA 通道。
    • 配置完成后,启动信号(硬件或软件)将触发 DMA 工作。
    • 在传输完成后,自动关闭 DMA 通道。

\7. 传输状态与中断

DMA 工作中可能会产生以下状态信号:

  • 完成中断:当传输计数器为 0 时,触发完成中断,通知 CPU 数据传输已结束。
  • 错误中断:当发生传输错误(如总线冲突)时,触发错误中断。
  • 半传输中断:在双缓冲模式下,完成一半传输后触发,通知 CPU 可以处理已传输的数据。

中断的使用可以让 DMA 实现完全自动化的数据传输,CPU 只需响应完成中断即可处理数据。


\8. 工作流程总结

  1. 配置 DMA 通道
    • 设置源地址(外设或存储器)。
    • 设置目标地址(存储器或外设)。
    • 设置传输方向和数据宽度。
  1. 启动 DMA
    • 配置触发方式(硬件或软件)。
    • 开启 DMA 通道。
  1. 数据传输
    • 传输计数器记录剩余数据量,传输完成后自动关闭 DMA 或触发中断。
  1. 后续处理
    • CPU 响应 DMA 完成中断,处理传输完成的数据。

5.DMA请求

STM32F103C8T6 DMA资源:DMA1(7个通道)

不同的通道开始请求转运的所对应的引脚有所不同,如果硬件请求,各个通道之间是不同的。如果是软件请求,则不受通道几的局限。

主要是对应基本结构图的这一部分:

6.数据宽度与对齐

当外设和存储器需要转运的数据的宽度决定了需要传输的操作,也就是如何去转运。大概就是如果大的数据转进小的,高位的数据就会舍去;如果小的数据转进大的,高位就会补0。

7.如何工作的

7.1 数据转运+DMA

目的就是将DataA的数据转运到DataB。

那么外设的起始地址就是填DataA的首地址,存储器的起始地址就是填DataB的首地址。

可以看出这里是存储器到存储器的转运,那么触发方式就是软件触发,是不需要硬件时机。

这种属于是复制转运,转运后DataA的数据并不会消失。

7.2 ADC扫描模式+DMA

左边是ADC转换,每一个通道转换完成后的数据会放进ADC_DR寄存器中,这时候就要通过DMA将其转运到存储器,防止下一个AD通道转后的编码数据将ADC_DR寄存器的上一个通道的数据给覆盖掉,因为对于常规的通道,是16个通道对应到一个寄存器的,只能临时存放一个通道的数据。

8.结构体和相关api

8.1 结构体

c 复制代码
typedef struct
{
  uint32_t DMA_PeripheralBaseAddr; /*!< Specifies the peripheral base address for DMAy Channelx. */

  uint32_t DMA_MemoryBaseAddr;     /*!< Specifies the memory base address for DMAy Channelx. */

  uint32_t DMA_DIR;                /*!< Specifies if the peripheral is the source or destination.
                                        This parameter can be a value of @ref DMA_data_transfer_direction */

  uint32_t DMA_BufferSize;         /*!< Specifies the buffer size, in data unit, of the specified Channel. 
                                        The data unit is equal to the configuration set in DMA_PeripheralDataSize
                                        or DMA_MemoryDataSize members depending in the transfer direction. */

  uint32_t DMA_PeripheralInc;      /*!< Specifies whether the Peripheral address register is incremented or not.
                                        This parameter can be a value of @ref DMA_peripheral_incremented_mode */

  uint32_t DMA_MemoryInc;          /*!< Specifies whether the memory address register is incremented or not.
                                        This parameter can be a value of @ref DMA_memory_incremented_mode */

  uint32_t DMA_PeripheralDataSize; /*!< Specifies the Peripheral data width.
                                        This parameter can be a value of @ref DMA_peripheral_data_size */

  uint32_t DMA_MemoryDataSize;     /*!< Specifies the Memory data width.
                                        This parameter can be a value of @ref DMA_memory_data_size */

  uint32_t DMA_Mode;               /*!< Specifies the operation mode of the DMAy Channelx.
                                        This parameter can be a value of @ref DMA_circular_normal_mode.
                                        @note: The circular buffer mode cannot be used if the memory-to-memory
                                              data transfer is configured on the selected Channel */

  uint32_t DMA_Priority;           /*!< Specifies the software priority for the DMAy Channelx.
                                        This parameter can be a value of @ref DMA_priority_level */

  uint32_t DMA_M2M;                /*!< Specifies if the DMAy Channelx will be used in memory-to-memory transfer.
                                        This parameter can be a value of @ref DMA_memory_to_memory */
}DMA_InitTypeDef;

\1. DMA_PeripheralBaseAddr

  • 作用:设置外设的基地址,用于指定 DMA 数据传输的外设端地址。

  • 典型值

    • 外设寄存器地址,例如 ADC1_BASEUSART1_BASE + DR_OFFSET
    • 如果是从外设到存储器(或相反),这个字段必须设置为外设的寄存器地址。

\2. DMA_MemoryBaseAddr

  • 作用:设置存储器的基地址,用于指定 DMA 数据传输的存储器端地址。

  • 典型值

    • 存储器的起始地址,例如 SRAM 中的某个变量地址或者数组地址。
    • 示例:(uint32_t)&bufferbuffer 是存储数据的缓冲区。

\3. DMA_DIR

  • 作用:指定数据传输方向,是从外设到存储器还是从存储器到外设。

  • 可选值

    • DMA_DIR_PeripheralDST:数据从存储器传输到外设。
    • DMA_DIR_PeripheralSRC:数据从外设传输到存储器。

\4. DMA_BufferSize

  • 作用:指定数据传输的大小,以数据单元(Data Unit)为单位。

  • 说明

    • 数据单元大小由 DMA_PeripheralDataSizeDMA_MemoryDataSize 确定。
    • 配置方法:用户根据传输数据的数量(如数组长度)设置。
    • 注意:不能超过硬件 DMA 通道的支持范围。

\5. DMA_PeripheralInc

  • 作用:指定外设地址在每次数据传输后是否自动递增。

  • 可选值

    • DMA_PeripheralInc_Enable:外设地址递增。
    • DMA_PeripheralInc_Disable:外设地址固定不变。
  • 应用场景

    • 通常外设地址固定,因此多数情况下为 DMA_PeripheralInc_Disable

\6. DMA_MemoryInc

  • 作用:指定存储器地址在每次数据传输后是否自动递增。

  • 可选值

    • DMA_MemoryInc_Enable:存储器地址递增。
    • DMA_MemoryInc_Disable:存储器地址固定不变。
  • 应用场景

    • 如果传输到连续的存储空间(如数组),设置为 Enable
    • 如果传输到单个存储器地址,设置为 Disable

\7. DMA_PeripheralDataSize

  • 作用:设置外设数据宽度。

  • 可选值

    • DMA_PeripheralDataSize_Byte:8 位。
    • DMA_PeripheralDataSize_HalfWord:16 位。
    • DMA_PeripheralDataSize_Word:32 位。
  • 说明 :需根据外设的寄存器宽度进行设置。例如,USART 数据寄存器为 8 位时,应选择 Byte


\8. DMA_MemoryDataSize

  • 作用:设置存储器数据宽度。

  • 可选值

    • DMA_MemoryDataSize_Byte:8 位。
    • DMA_MemoryDataSize_HalfWord:16 位。
    • DMA_MemoryDataSize_Word:32 位。
  • 说明 :与 DMA_PeripheralDataSize 配合使用,确保数据传输正常。


\9. DMA_Mode

  • 作用:设置 DMA 的操作模式(普通模式或循环模式)。

  • 可选值

    • DMA_Mode_Normal:普通模式,传输完成后停止。
    • DMA_Mode_Circular:循环模式,传输完成后自动重新开始。
  • 说明

    • 循环模式适用于连续数据采样场景(如 ADC 连续采样)。
    • 普通模式适用于单次传输任务。

\10. DMA_Priority

  • 作用:设置 DMA 通道的优先级。

  • 可选值

    • DMA_Priority_Low:低优先级。
    • DMA_Priority_Medium:中优先级。
    • DMA_Priority_High:高优先级。
    • DMA_Priority_VeryHigh:非常高优先级。
  • 说明:当多个 DMA 通道请求同时发生时,优先级高的通道会优先传输。


\11. DMA_M2M

  • 作用:指定是否启用存储器到存储器(M2M)传输模式。

  • 可选值

    • DMA_M2M_Enable:启用 M2M 传输模式。
    • DMA_M2M_Disable:禁用 M2M 传输模式。
  • 说明

    • M2M 模式允许直接在内存之间传输数据,不需要外设参与。

以下是一个配置 DMA 用于 ADC 连续采样的示例:

c 复制代码
DMA_InitTypeDef DMA_InitStructure;

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // ADC 数据寄存器地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_Buffer;    // 存储采样数据的缓冲区地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;              // 数据从外设到存储器
DMA_InitStructure.DMA_BufferSize = 100;                         // 传输 100 个数据单元
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 外设地址不递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         // 存储器地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 外设数据宽度为 16 位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;         // 存储器数据宽度为 16 位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                 // 循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High;             // 高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                    // 禁用内存到内存模式

DMA_Init(DMA1_Channel1, &DMA_InitStructure);                    // 初始化 DMA 通道 1
DMA_Cmd(DMA1_Channel1, ENABLE);                                // 启用 DMA

8.2 api

1. void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx)
  • 作用

    • 将指定的 DMA 通道配置恢复到默认值,类似于复位操作。
    • 清除通道相关的所有配置和寄存器值。
  • 参数

    • DMAy_Channelx:指定需要重置的 DMA 通道,DMA1_Channel1 ~ DMA1_Channel7,或 DMA2_Channel1 ~ DMA2_Channel5
  • 使用场景

    • 在重新配置某个 DMA 通道之前,建议调用此函数进行复位,避免遗留配置问题。
  • 代码示例

c 复制代码
DMA_DeInit(DMA1_Channel1); // 重置 DMA1 通道 1

2. void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct)
  • 作用

    • 使用 DMA_InitTypeDef 结构体配置指定的 DMA 通道。
  • 参数

    • DMAy_Channelx:指定 DMA 通道(同上)。
    • DMA_InitStruct:指向包含 DMA 配置信息的初始化结构体。
  • 使用场景

    • 需要为某个 DMA 通道设置传输方向、外设地址、存储器地址、数据宽度、模式等参数。
  • 注意事项

    • 调用 DMA_DeInit 复位通道后再初始化。
    • 必须配置好 DMA_InitTypeDef 中的所有参数。
  • 代码示例

c 复制代码
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // 外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_Buffer;    // 存储器基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;              // 数据方向
DMA_InitStructure.DMA_BufferSize = 100;                         // 数据大小
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                 // 循环模式
DMA_Init(DMA1_Channel1, &DMA_InitStructure);                    // 初始化 DMA 通道

3. void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct)
  • 作用

    • DMA_InitTypeDef 初始化为默认值。
  • 参数

    • DMA_InitStruct:指向 DMA_InitTypeDef 结构体的指针。
  • 默认值

    • 数据方向:DMA_DIR_PeripheralDST
    • 外设/存储器地址:0
    • 数据宽度:Byte
    • 优先级:Low
    • 模式:Normal
  • 使用场景

    • 准备使用 DMA_Init 之前,调用此函数初始化结构体,再根据需求修改。
  • 代码示例

c 复制代码
DMA_InitTypeDef DMA_InitStructure;
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // 修改部分配置

4. void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState)
  • 作用

    • 启用或禁用指定的 DMA 通道。
  • 参数

    • DMAy_Channelx:指定 DMA 通道。
    • NewState:DMA 通道状态,ENABLE(启用)或 DISABLE(禁用)。
  • 使用场景

    • 在配置完成后,启用 DMA 通道以启动传输。
    • 如果需要停止传输,可以禁用 DMA 通道。
  • 代码示例

c 复制代码
DMA_Cmd(DMA1_Channel1, ENABLE); // 启用 DMA 通道 1

5. void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState)
  • 作用

    • 配置指定的 DMA 中断。
  • 参数

    • DMAy_Channelx:指定 DMA 通道。
    • DMA_IT:要配置的中断源,可以是以下值:
      • DMA_IT_TC:传输完成中断。
      • DMA_IT_HT:半传输完成中断。
      • DMA_IT_TE:传输错误中断。
    • NewState:中断状态,ENABLE(启用)或 DISABLE(禁用)。
  • 使用场景

    • 在需要处理 DMA 中断时使用。
  • 代码示例

c 复制代码
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); // 启用传输完成中断

6. void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber)
  • 作用

    • 设置当前要传输的数据单元数量。
  • 参数

    • DMAy_Channelx:指定 DMA 通道。
    • DataNumber:传输的数据单元数量。
  • 使用场景

    • 需要重新调整 DMA 的传输数据量时使用。
  • 代码示例

c 复制代码
DMA_SetCurrDataCounter(DMA1_Channel1, 50); // 设置传输 50 个数据单元

7. uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx)
  • 作用

    • 获取当前剩余的数据单元数量。
  • 参数

    • DMAy_Channelx:指定 DMA 通道。
  • 返回值

    • 剩余数据单元数量。
  • 使用场景

    • 在传输过程中监控剩余数据量。
  • 代码示例

c 复制代码
uint16_t remaining = DMA_GetCurrDataCounter(DMA1_Channel1);

8. FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)
  • 作用

    • 检查指定的 DMA 标志状态。
  • 参数

    • DMAy_FLAG:要检查的标志位,可以是以下值:
      • DMA1_FLAG_TC1:通道 1 传输完成标志。
      • DMA1_FLAG_HT1:通道 1 半传输标志。
      • DMA1_FLAG_TE1:通道 1 传输错误标志。
      • (其他通道类似)
  • 返回值

    • SETRESET
  • 代码示例

c 复制代码
if (DMA_GetFlagStatus(DMA1_FLAG_TC1) == SET) {
    // 传输完成
}

9. void DMA_ClearFlag(uint32_t DMAy_FLAG)
  • 作用

    • 清除指定的 DMA 标志位。
  • 参数

    • DMAy_FLAG:要清除的标志位。
  • 代码示例

c 复制代码
DMA_ClearFlag(DMA1_FLAG_TC1); // 清除通道 1 的传输完成标志

10. ITStatus DMA_GetITStatus(uint32_t DMAy_IT)
  • 作用

    • 检查指定的 DMA 中断状态。
  • 参数

    • DMAy_IT:要检查的中断标志,可以是以下值:
      • DMA1_IT_TC1:通道 1 传输完成中断。
      • DMA1_IT_HT1:通道 1 半传输中断。
      • DMA1_IT_TE1:通道 1 传输错误中断。
  • 返回值

    • SETRESET
  • 代码示例

c 复制代码
if (DMA_GetITStatus(DMA1_IT_TC1) == SET) {
    // 处理传输完成中断
}

11. void DMA_ClearITPendingBit(uint32_t DMAy_IT)
  • 作用

    • 清除指定的 DMA 中断挂起位。
  • 参数

    • DMAy_IT:要清除的中断标志。
  • 代码示例

c 复制代码
DMA_ClearITPendingBit(DMA1_IT_TC1); // 清除传输完成中断挂起位

这些函数为 DMA 的初始化、启动、状态检查和中断处理提供了全面的支持。在使用时,需按顺序完成以下步骤:

  1. 调用 DMA_DeInit 清除通道配置。
  2. 调用 DMA_StructInit 初始化结构体,并配置相关参数。
  3. 调用 DMA_Init 配置 DMA 通道。
  4. 调用 DMA_Cmd 启用 DMA。
  5. 在传输完成或中断触发时,使用状态检查和标志清除函数。

9.实验

9.1 DMA转运

📎8-1 DMA数据转运.zip

User:

Hardware:

System:

9.2 DMA+AD多通道

📎8-2 DMA+AD多通道.zip

相关推荐
吃货界的硬件攻城狮1 小时前
【STM32 学习笔记】ADC数模转换器
笔记·stm32·单片机·学习
小昭dedug5 小时前
功能安全的关键——MCU锁步核技术全解析(含真实应用方案)
单片机·嵌入式硬件
负里556 小时前
STM32-模电
嵌入式硬件
BW.SU6 小时前
单片机 + 图像处理芯片 + TFT彩屏 指示灯控件
单片机·嵌入式硬件·人机交互·控件·触摸屏设计·指示灯·液晶屏
newtonltr7 小时前
CANopen TPDO 配置详解:对象 1800h、1A00h 与实践指南
stm32·canopen
逼子格7 小时前
二极管钳位电路——Multisim电路仿真
嵌入式硬件·硬件工程·硬件工程师·滤波器·硬件工程师真题·钳位电路·二极管钳位电路
思考的味道7 小时前
STM32F446 RTC在VDD/VDDA关闭后失振问题的分析与解决
嵌入式硬件
KingQian20187 小时前
单片机嵌入式滤波算法库
单片机·嵌入式硬件·算法
LXL_248 小时前
B站Michale_ee——ESP32_IDF SDK——WiFi_1 AP、STA模式、TCP、UDP
嵌入式硬件