描述 #
该文件定义了 CH32V00x 系列微控制器 DMA(直接存储器访问)外设的固件库函数原型、数据结构及常量宏。DMA 用于在不占用 CPU 资源的情况下实现外设与内存、内存与内存之间的高效数据传输,适用于高速数据采集、串口/ADC 缓冲、图像处理等场景。本库支持 7 个 DMA 通道,每个通道可独立配置传输方向、数据宽度、地址递增模式、优先级和循环模式,极大提升系统并发处理能力。
常量 #
DMA_data_transfer_direction
#
指定 DMA 传输方向,决定外设与内存谁是源、谁是目标。
在嵌入式系统中,通常外设(如 ADC、UART)作为数据源(SRC),内存作为目标(DST),但也可用于内存到内存的复制操作,如缓存刷新或数据搬移。
| 名称 | 值 | 简述 |
|---|---|---|
DMA_DIR_PeripheralDST |
0x00000010 |
外设为数据源,内存为目标(外设 → 内存) |
DMA_DIR_PeripheralSRC |
0x00000000 |
内存为数据源,外设为目标(内存 → 外设) |
以上所有值都强制转换为
uint32_t。
DMA_peripheral_incremented_mode
#
控制外设地址寄存器在每次传输后是否自增。
适用于外设寄存器地址固定(如 ADC 数据寄存器)或需连续读取多个寄存器(如多通道 ADC)的场景。若地址不变,则可避免地址错误或重复读取。
| 名称 | 值 | 简述 |
|---|---|---|
DMA_PeripheralInc_Enable |
0x00000040 |
外设地址在每次传输后自动递增 |
DMA_PeripheralInc_Disable |
0x00000000 |
外设地址保持不变 |
以上所有值都强制转换为
uint32_t。
DMA_memory_incremented_mode
#
控制内存地址寄存器在每次传输后是否自增。
这是最常用模式,用于连续写入或读取数组、缓冲区。若禁用,则所有数据都写入/读取同一内存地址,通常用于单点寄存器操作或特殊硬件接口。
| 名称 | 值 | 简述 |
|---|---|---|
DMA_MemoryInc_Enable |
0x00000080 |
内存地址在每次传输后自动递增 |
DMA_MemoryInc_Disable |
0x00000000 |
内存地址保持不变 |
以上所有值都强制转换为
uint32_t。
DMA_peripheral_data_size
#
定义外设端的数据宽度,影响单次传输的数据量。
选择与外设寄存器实际宽度匹配的值可避免数据截断或对齐错误。例如,UART 发送缓冲区通常为字节,而 ADC 通常为半字(16 位)。
| 名称 | 值 | 简述 |
|---|---|---|
DMA_PeripheralDataSize_Byte |
0x00000000 |
外设数据宽度为 8 位(字节) |
DMA_PeripheralDataSize_HalfWord |
0x00000100 |
外设数据宽度为 16 位(半字) |
DMA_PeripheralDataSize_Word |
0x00000200 |
外设数据宽度为 32 位(字) |
以上所有值都强制转换为
uint32_t。
DMA_memory_data_size
#
定义内存端的数据宽度,需与外设端匹配以保证传输一致性。
若内存与外设宽度不一致,DMA 控制器会自动进行数据扩展或截断,但可能导致性能下降或数据错误,建议严格对齐。
| 名称 | 值 | 简述 |
|---|---|---|
DMA_MemoryDataSize_Byte |
0x00000000 |
内存数据宽度为 8 位(字节) |
DMA_MemoryDataSize_HalfWord |
0x00000400 |
内存数据宽度为 16 位(半字) |
DMA_MemoryDataSize_Word |
0x00000800 |
内存数据宽度为 32 位(字) |
以上所有值都强制转换为
uint32_t。
DMA_circular_normal_mode
#
设置 DMA 传输模式,决定传输完成后是否自动重置并重复。
循环模式适用于持续采集(如 ADC 连续采样、音频流),可避免 CPU 频繁干预;正常模式适用于一次性传输,完成后自动停止。
| 名称 | 值 | 简述 |
|---|---|---|
DMA_Mode_Circular |
0x00000020 |
传输完成后自动重置缓冲区指针,进入循环模式 |
DMA_Mode_Normal |
0x00000000 |
传输完成后停止,需软件重新启动 |
以上所有值都强制转换为
uint32_t。
DMA_priority_level
#
设置 DMA 通道的软件优先级,用于多通道竞争时的调度。
高优先级通道在总线冲突时优先获得访问权,适用于实时性要求高的外设(如高速串口、定时器触发 ADC)。低优先级通道适合后台数据搬运。
| 名称 | 值 | 简述 |
|---|---|---|
DMA_Priority_VeryHigh |
0x00003000 |
最高优先级,抢占其他通道 |
DMA_Priority_High |
0x00002000 |
高优先级,优先于中低 |
DMA_Priority_Medium |
0x00001000 |
中等优先级 |
DMA_Priority_Low |
0x00000000 |
最低优先级,仅在总线空闲时执行 |
以上所有值都强制转换为
uint32_t。
DMA_memory_to_memory
#
启用或禁用内存到内存的传输模式。
此模式下 DMA 不依赖外设,仅在两个内存区域间搬运数据,常用于快速内存拷贝、缓冲区交换等场景。注意:循环模式不支持内存到内存传输。
| 名称 | 值 | 简述 |
|---|---|---|
DMA_M2M_Enable |
0x00004000 |
启用内存到内存传输模式 |
DMA_M2M_Disable |
0x00000000 |
禁用内存到内存传输(默认) |
以上所有值都强制转换为
uint32_t。
DMA_interrupts_definition
#
定义 DMA 通道的中断使能位,用于触发中断服务函数。
这些位与 DMA_ITConfig() 配合使用,可分别使能传输完成、半传输、传输错误中断,便于实现分段处理或错误恢复。
| 名称 | 值 | 简述 |
|---|---|---|
DMA_IT_TC |
0x00000002 |
传输完成中断使能 |
DMA_IT_HT |
0x00000004 |
半传输中断使能(缓冲区一半完成) |
DMA_IT_TE |
0x00000008 |
传输错误中断使能 |
以上所有值都强制转换为
uint32_t。
DMA1_IT_GL1 至 DMA1_IT_TE7
#
DMA1 每个通道的独立中断标志位,用于中断服务程序中判断具体中断源。
每个通道有 4 个标志:全局(GL)、传输完成(TC)、半传输(HT)、传输错误(TE)。通过位掩码可快速定位中断来源,避免轮询。
| 名称 | 值 | 简述 |
|---|---|---|
DMA1_IT_GL1 |
0x00000001 |
DMA1 通道1 全局中断标志 |
DMA1_IT_TC1 |
0x00000002 |
DMA1 通道1 传输完成中断标志 |
DMA1_IT_HT1 |
0x00000004 |
DMA1 通道1 半传输中断标志 |
DMA1_IT_TE1 |
0x00000008 |
DMA1 通道1 传输错误中断标志 |
DMA1_IT_GL2 |
0x00000010 |
DMA1 通道2 全局中断标志 |
DMA1_IT_TC2 |
0x00000020 |
DMA1 通道2 传输完成中断标志 |
DMA1_IT_HT2 |
0x00000040 |
DMA1 通道2 半传输中断标志 |
DMA1_IT_TE2 |
0x00000080 |
DMA1 通道2 传输错误中断标志 |
DMA1_IT_GL3 |
0x00000100 |
DMA1 通道3 全局中断标志 |
DMA1_IT_TC3 |
0x00000200 |
DMA1 通道3 传输完成中断标志 |
DMA1_IT_HT3 |
0x00000400 |
DMA1 通道3 半传输中断标志 |
DMA1_IT_TE3 |
0x00000800 |
DMA1 通道3 传输错误中断标志 |
DMA1_IT_GL4 |
0x00001000 |
DMA1 通道4 全局中断标志 |
DMA1_IT_TC4 |
0x00002000 |
DMA1 通道4 传输完成中断标志 |
DMA1_IT_HT4 |
0x00004000 |
DMA1 通道4 半传输中断标志 |
DMA1_IT_TE4 |
0x00008000 |
DMA1 通道4 传输错误中断标志 |
DMA1_IT_GL5 |
0x00010000 |
DMA1 通道5 全局中断标志 |
DMA1_IT_TC5 |
0x00020000 |
DMA1 通道5 传输完成中断标志 |
DMA1_IT_HT5 |
0x00040000 |
DMA1 通道5 半传输中断标志 |
DMA1_IT_TE5 |
0x00080000 |
DMA1 通道5 传输错误中断标志 |
DMA1_IT_GL6 |
0x00100000 |
DMA1 通道6 全局中断标志 |
DMA1_IT_TC6 |
0x00200000 |
DMA1 通道6 传输完成中断标志 |
DMA1_IT_HT6 |
0x00400000 |
DMA1 通道6 半传输中断标志 |
DMA1_IT_TE6 |
0x00800000 |
DMA1 通道6 传输错误中断标志 |
DMA1_IT_GL7 |
0x01000000 |
DMA1 通道7 全局中断标志 |
DMA1_IT_TC7 |
0x02000000 |
DMA1 通道7 传输完成中断标志 |
DMA1_IT_HT7 |
0x04000000 |
DMA1 通道7 半传输中断标志 |
DMA1_IT_TE7 |
0x08000000 |
DMA1 通道7 传输错误中断标志 |
以上所有值都强制转换为
uint32_t。
DMA1_FLAG_GL1 至 DMA1_FLAG_TE7
#
DMA1 每个通道的状态标志位,用于轮询查询传输状态。
与中断标志位一一对应,但用于非中断模式下的状态检测,如轮询等待传输完成或检查错误。
| 名称 | 值 | 简述 |
|---|---|---|
DMA1_FLAG_GL1 |
0x00000001 |
DMA1 通道1 全局状态标志 |
DMA1_FLAG_TC1 |
0x00000002 |
DMA1 通道1 传输完成状态标志 |
DMA1_FLAG_HT1 |
0x00000004 |
DMA1 通道1 半传输状态标志 |
DMA1_FLAG_TE1 |
0x00000008 |
DMA1 通道1 传输错误状态标志 |
DMA1_FLAG_GL2 |
0x00000010 |
DMA1 通道2 全局状态标志 |
DMA1_FLAG_TC2 |
0x00000020 |
DMA1 通道2 传输完成状态标志 |
DMA1_FLAG_HT2 |
0x00000040 |
DMA1 通道2 半传输状态标志 |
DMA1_FLAG_TE2 |
0x00000080 |
DMA1 通道2 传输错误状态标志 |
DMA1_FLAG_GL3 |
0x00000100 |
DMA1 通道3 全局状态标志 |
DMA1_FLAG_TC3 |
0x00000200 |
DMA1 通道3 传输完成状态标志 |
DMA1_FLAG_HT3 |
0x00000400 |
DMA1 通道3 半传输状态标志 |
DMA1_FLAG_TE3 |
0x00000800 |
DMA1 通道3 传输错误状态标志 |
DMA1_FLAG_GL4 |
0x00001000 |
DMA1 通道4 全局状态标志 |
DMA1_FLAG_TC4 |
0x00002000 |
DMA1 通道4 传输完成状态标志 |
DMA1_FLAG_HT4 |
0x00004000 |
DMA1 通道4 半传输状态标志 |
DMA1_FLAG_TE4 |
0x00008000 |
DMA1 通道4 传输错误状态标志 |
DMA1_FLAG_GL5 |
0x00010000 |
DMA1 通道5 全局状态标志 |
DMA1_FLAG_TC5 |
0x00020000 |
DMA1 通道5 传输完成状态标志 |
DMA1_FLAG_HT5 |
0x00040000 |
DMA1 通道5 半传输状态标志 |
DMA1_FLAG_TE5 |
0x00080000 |
DMA1 通道5 传输错误状态标志 |
DMA1_FLAG_GL6 |
0x00100000 |
DMA1 通道6 全局状态标志 |
DMA1_FLAG_TC6 |
0x00200000 |
DMA1 通道6 传输完成状态标志 |
DMA1_FLAG_HT6 |
0x00400000 |
DMA1 通道6 半传输状态标志 |
DMA1_FLAG_TE6 |
0x00800000 |
DMA1 通道6 传输错误状态标志 |
DMA1_FLAG_GL7 |
0x01000000 |
DMA1 通道7 全局状态标志 |
DMA1_FLAG_TC7 |
0x02000000 |
DMA1 通道7 传输完成状态标志 |
DMA1_FLAG_HT7 |
0x04000000 |
DMA1 通道7 半传输状态标志 |
DMA1_FLAG_TE7 |
0x08000000 |
DMA1 通道7 传输错误状态标志 |
以上所有值都强制转换为
uint32_t。
枚举 #
无
结构体 #
DMA_InitTypeDef
#
DMA 通道初始化结构体,用于配置一次完整的 DMA 传输任务。
该结构体封装了所有必要参数,通过 DMA_Init() 一次性写入寄存器,极大简化了配置流程。开发者只需填充结构体,无需直接操作寄存器,提高代码可读性与可移植性。
| 名称 | 类型 | 简述 |
|---|---|---|
DMA_PeripheralBaseAddr |
uint32_t |
外设寄存器的基地址,如 ADC1_DR、USART1_DR 等 |
DMA_MemoryBaseAddr |
uint32_t |
内存缓冲区的起始地址,通常为数组或变量地址 |
DMA_DIR |
uint32_t |
传输方向,参见 DMA_data_transfer_direction 宏定义 |
DMA_BufferSize |
uint32_t |
传输的数据单元数量,每个单元大小由 DMA_PeripheralDataSize 或 DMA_MemoryDataSize 决定 |
DMA_PeripheralInc |
uint32_t |
外设地址是否递增,参见 DMA_peripheral_incremented_mode |
DMA_MemoryInc |
uint32_t |
内存地址是否递增,参见 DMA_memory_incremented_mode |
DMA_PeripheralDataSize |
uint32_t |
外设数据宽度,参见 DMA_peripheral_data_size |
DMA_MemoryDataSize |
uint32_t |
内存数据宽度,参见 DMA_memory_data_size |
DMA_Mode |
uint32_t |
传输模式,循环或正常,参见 DMA_circular_normal_mode |
DMA_Priority |
uint32_t |
通道优先级,参见 DMA_priority_level |
DMA_M2M |
uint32_t |
是否启用内存到内存模式,参见 DMA_memory_to_memory |
函数 #
DMA_DeInit
#
void DMA_DeInit(DMA_Channel_TypeDef *DMAy_Channelx)
将指定 DMA 通道的所有寄存器恢复为复位默认值,停止当前传输并清除所有中断标志。
此函数通过清零控制寄存器和计数器实现重置,同时清除对应通道的中断挂起标志,确保通道处于干净状态,适合在重新配置前调用。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMAy_Channelx |
DMA_Channel_TypeDef * |
DMA 通道指针,y 为 1(仅支持 DMA1),x 为 1~7,如 DMA1_Channel1 |
返回值:
无
DMA_Init
#
void DMA_Init(DMA_Channel_TypeDef *DMAy_Channelx, DMA_InitTypeDef *DMA_InitStruct)
根据传入的初始化结构体配置指定 DMA 通道的全部参数。
此函数将结构体中的所有字段写入 DMA 控制寄存器(CFGR、CNTR、PADDR、MADDR),完成一次完整的通道配置。调用前必须确保时钟已使能(RCC),且结构体已正确初始化。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMAy_Channelx |
DMA_Channel_TypeDef * |
DMA 通道指针,如 DMA1_Channel3 |
DMA_InitStruct |
DMA_InitTypeDef * |
指向已填充配置参数的结构体指针 |
返回值:
无
DMA_StructInit
#
void DMA_StructInit(DMA_InitTypeDef *DMA_InitStruct)
将 DMA 初始化结构体的所有成员设置为默认值,便于快速初始化。
此函数为开发者提供“安全起点”,避免因未初始化字段导致不可预测行为。默认配置为:内存到外设、字节宽度、低优先级、非循环、非内存到内存模式。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMA_InitStruct |
DMA_InitTypeDef * |
待初始化的结构体指针 |
返回值:
无
DMA_Cmd
#
void DMA_Cmd(DMA_Channel_TypeDef *DMAy_Channelx, FunctionalState NewState)
启用或禁用指定 DMA 通道的传输功能。
仅在使能后,DMA 才会响应传输请求。禁用通道不会清除配置,仅暂停传输,适合动态启停(如按需触发 ADC 采样)。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMAy_Channelx |
DMA_Channel_TypeDef * |
DMA 通道指针,如 DMA1_Channel5 |
NewState |
FunctionalState |
ENABLE(启用)或 DISABLE(禁用) |
返回值:
无
DMA_ITConfig
#
void DMA_ITConfig(DMA_Channel_TypeDef *DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState)
启用或禁用指定 DMA 通道的中断源(传输完成、半传输、传输错误)。
中断可触发中断服务函数(ISR),用于处理缓冲区满、数据错误或分段处理。注意:需在 NVIC 中使能对应中断线。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMAy_Channelx |
DMA_Channel_TypeDef * |
DMA 通道指针,如 DMA1_Channel2 |
DMA_IT |
uint32_t |
中断源,如 DMA_IT_TC、DMA_IT_HT、DMA_IT_TE |
NewState |
FunctionalState |
ENABLE 或 DISABLE |
返回值:
无
DMA_SetCurrDataCounter
#
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef *DMAy_Channelx, uint16_t DataNumber)
动态修改当前 DMA 通道的剩余数据计数器值。
可用于运行时调整传输长度,如在循环模式中动态改变缓冲区大小,或在中断中重置剩余计数以实现自适应传输。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMAy_Channelx |
DMA_Channel_TypeDef * |
DMA 通道指针 |
DataNumber |
uint16_t |
新的剩余数据单元数量(0~65535) |
返回值:
无
DMA_GetCurrDataCounter
#
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef *DMAy_Channelx)
读取当前 DMA 通道剩余未传输的数据单元数量。
可用于监控传输进度,如在循环模式中判断缓冲区填充程度,或在非循环模式中确认是否完成。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMAy_Channelx |
DMA_Channel_TypeDef * |
DMA 通道指针 |
返回值:
当前剩余数据单元数(0 表示传输完成)
DMA_GetFlagStatus
#
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG)
查询指定 DMA 标志位的状态(SET 或 RESET),用于轮询方式检测传输状态。
适用于无中断系统或调试阶段,可判断是否完成、是否出错等。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMAy_FLAG |
uint32_t |
标志位,如 DMA1_FLAG_TC3、DMA1_FLAG_TE1 |
返回值:
SET(标志置位)或 RESET(标志清零)
DMA_ClearFlag
#
void DMA_ClearFlag(uint32_t DMAy_FLAG)
清除指定的 DMA 状态标志位。
必须在处理完中断或轮询事件后手动清除,否则标志将一直置位,导致重复触发或误判。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMAy_FLAG |
uint32_t |
要清除的标志,如 DMA1_FLAG_HT5 |
返回值:
无
DMA_GetITStatus
#
ITStatus DMA_GetITStatus(uint32_t DMAy_IT)
查询指定 DMA 中断标志是否被触发(SET 或 RESET),用于中断服务函数中判断中断来源。
与 DMA_GetFlagStatus 功能类似,但用于中断上下文,通常与 DMA_ClearITPendingBit 配合使用。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMAy_IT |
uint32_t |
中断标志,如 DMA1_IT_TC4、DMA1_IT_TE7 |
返回值:
SET(中断发生)或 RESET(未发生)
DMA_ClearITPendingBit
#
void DMA_ClearITPendingBit(uint32_t DMAy_IT)
清除指定的 DMA 中断挂起位,防止重复进入中断服务程序。
在中断服务函数末尾必须调用此函数,否则中断会持续触发,导致系统死循环。
参数:
| 名称 | 类型 | 简述 |
|---|---|---|
DMAy_IT |
uint32_t |
要清除的中断标志,如 DMA1_IT_TC2 |
返回值:
无