GD32中的DMA使用教程
一、概述
- 平台:GD32F4XX
- 资源:DMA,当前系列的DMA可分为DMA0和DMA1,每个DMA各有8个通道,总共16个通道可以映射到外设,提供使用
- 数据:长度最大65536,支持8位,16位和32位的数据宽度
二、外设请求
三、查表
在手册中获取到DMA的外设请求表后,就需要根据“外设功能”去查表,以SPI2为例
- 在表格中搜索SPI2_RX,出现在两个位置:位置A---通道0,位置B---通道2;
- 在表格中搜索SPI2_TX,出现在两个位置:位置A---通道5,位置B---通道7;
- 确定通道号:TX---DMA0_CH5,请求来源000,RX---DMA0_CH0,请求来源000
四、DMA初始化配置
void dma_spi2_slave_tx_config(uint8_t *buffer, uint32_t len){ /* 1. 使能 DMA 时钟 */ rcu_periph_clock_enable(RCU_DMA0); /* 2. 复位通道 */ dma_deinit(DMA0, DMA_CH5); /* 3. 关键配置:查表得出的 PERIEN 值 */ // 根据你的表:SPI2_TX 在通道 5 对应的 PERIEN 是 000 // 库函数通常定义为 DMA_PERIPH_SELECT_P0、DMA_PERIPH_SELECT_P1... 或直接传入 0 dma_periph_select_config(DMA0, DMA_CH5, DMA_PERIPH_SELECT_P0); /* 4. 常规初始化 */ dma_parameter_struct dma_init_struct; dma_struct_para_init(&dma_init_struct); dma_init_struct.periph_addr = (uint32_t)&SPI_DATA(SPI2); dma_init_struct.memory_addr = (uint32_t)buffer; dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; // TX是内存到外设 // ... 其他内存地址、长度、增量模式配置 ... dma_init_struct.number = len; dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; dma_init(DMA0, DMA_CH5, &dma_init_struct); /* 5. 使能通道 */ dma_channel_enable(DMA0, DMA_CH5); }五、外设初始化配置---SPI为例
/* 2. 配置 SPI2 为从机模式 */ void spi2_slave_config(void) { spi_parameter_struct spi_init_struct; rcu_periph_clock_enable(RCU_SPI2); // 注意:从机模式下 GPIO 也要正确配置,SCK/MOSI/NSS 为输入,MISO 为推挽复用输出 spi_init_struct.device_mode = SPI_SLAVE; // 设为从机 spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; spi_init_struct.nss = SPI_NSS_HARD; // 通常从机由硬件 NSS 选中 spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; // 需与主机一致 spi_init_struct.endian = SPI_ENDIAN_MSB; spi_init(SPI2, &spi_init_struct); // 开启 SPI 的 DMA 发送触发 spi_dma_enable(SPI2, SPI_DMA_TRANSMIT); spi_enable(SPI2); }