GD32 SPI DMA收发

由于需求用到GD32 SPI,

故做相关实验记录分享,本实验为 SPI DMA 发送与接收 16bit 数据, GD32 相关配置如下

GD32 F30x系列 DMA配置如下

 

SPI DMA 发:使用SPI0,对应的DMA为0 Channel 2。 

注意打开 对应 DMA 与 SPI 相关时钟, DMA write 使用时需要先拉低 NSS,发送结束,拉高NSS

void SPI0_config(void)
{
	rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_SPI0);
	rcu_periph_clock_enable(RCU_DMA0);

    /* SPI0 GPIO config: SCK/PA5, MISO/PA6, MOSI/PA7 */
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 |GPIO_PIN_6 | GPIO_PIN_7);
    /* PA3 as NSS */
    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
	
	/* SPI0 parameter config */
	spi_parameter_struct  spi_init_struct;
    spi_init_struct.trans_mode           = SPI_TRANSMODE_BDTRANSMIT;
    spi_init_struct.device_mode          = SPI_MASTER;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_16BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
    spi_init_struct.nss                  = SPI_NSS_SOFT;
    spi_init_struct.prescale             = SPI_PSC_256;
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
    spi_init(SPI0, &spi_init_struct);
	
	spi_enable(SPI0);
}


void DMASPI0_config(void)  //DMA 
{
	  
    dma_parameter_struct dma_init_struct;
    
    /* SPI0 transmit dma config:DMA0-DMA_CH2  */
    dma_deinit(DMA0, DMA_CH2);
    dma_init_struct.periph_addr  = (uint32_t)(&SPI_DATA(SPI0));
    dma_init_struct.memory_addr  = (uint32_t)TestData;
    dma_init_struct.direction    = DMA_MEMORY_TO_PERIPHERAL;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_LOW;
    dma_init_struct.number       = 6;
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_init(DMA0, DMA_CH2, &dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH2);
    dma_memory_to_memory_disable(DMA0, DMA_CH2);
	dma_channel_disable(DMA0,DMA_CH2);	
	
}

void DMASPI0_write(uint16_t *buf, uint16_t len)  //DMA write
{
	dma_deinit(DMA0, DMA_CH2);
	dma_parameter_struct dma_init_struct;
    dma_init_struct.periph_addr  = (uint32_t)(&SPI_DATA(SPI0));
    dma_init_struct.memory_addr  = (uint32_t)buf;
    dma_init_struct.direction    = DMA_MEMORY_TO_PERIPHERAL;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_LOW;
    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(DMA0, DMA_CH2, &dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH2);
    dma_memory_to_memory_disable(DMA0, DMA_CH2);

	spi_dma_enable(SPI0, SPI_DMA_TRANSMIT);
	dma_channel_enable(DMA0, DMA_CH2);
	while(!dma_flag_get(DMA0,DMA_CH2, DMA_FLAG_FTF));

}

SPI DMA 收: 使用SPI2    DMA1 Channel 0

void SPI2_config(void)  //slave
{	
	rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_DMA1);
    rcu_periph_clock_enable(RCU_SPI2); 
	
	/* SPI2 GPIO config: NSS/PA15, SCK/PB3, MISO/PB4, MOSI/PB5  DMA */
    gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3 | GPIO_PIN_5);
    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
    

    /* SPI2 parameter config */
	spi_parameter_struct spi_init_struct;
    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.device_mode          = SPI_SLAVE;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_16BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
    spi_init_struct.nss                  = SPI_NSS_SOFT;
    spi_init_struct.prescale             = SPI_PSC_256;
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
    spi_init(SPI2, &spi_init_struct);

    /* enable SPI2 */
    spi_enable(SPI2);
}

void SPI2DMA1_config(void)  //DMA SLAVE
{
	rcu_periph_clock_enable(RCU_DMA1);  
    dma_parameter_struct dma_init_struct;
    
    /* SPI0 transmit dma config:DMA0-DMA_CH2  */
    dma_deinit(DMA1, DMA_CH0);
    dma_init_struct.periph_addr  = (uint32_t)(&SPI_DATA(SPI2));
    dma_init_struct.memory_addr  = (uint32_t)RECV;
    dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_HIGH;
    dma_init_struct.number       = 6;
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_init(DMA1, DMA_CH0, &dma_init_struct);
    /* configure DMA mode */
	
    dma_circulation_disable(DMA1, DMA_CH0);
    dma_memory_to_memory_disable(DMA1, DMA_CH0);
	dma_channel_disable(DMA1,DMA_CH0);	
}

void SPI2DMA1_read(uint16_t *buf, uint16_t len)
{
	dma_parameter_struct dma_init_struct;
    
    /* SPI0 transmit dma config:DMA0-DMA_CH2  */
    dma_deinit(DMA1, DMA_CH0);
    dma_init_struct.periph_addr  = (uint32_t)(&SPI_DATA(SPI2));
    dma_init_struct.memory_addr  = (uint32_t)buf;
    dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_HIGH;
    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(DMA1, DMA_CH0, &dma_init_struct);
    /* configure DMA mode */
	
    dma_circulation_disable(DMA1, DMA_CH0);
    dma_memory_to_memory_disable(DMA1, DMA_CH0);
	
	
	spi_dma_enable(SPI2, SPI_DMA_RECEIVE);
	dma_channel_enable(DMA1, DMA_CH0);
	
	while(!dma_flag_get(DMA1,DMA_CH0, DMA_FLAG_FTF));
//	for(int i=0;i<6;i++){
//		printf("%04x ",buf[i]);
//	}
//	printf("\r\n");
//	memset(buf,0,sizeof(buf));
}

GD32 SPI DMA通信是指在GD32系列微控制器中使用SPI接口和DMA进行数据传输的一种通信方式。 SPI(Serial Peripheral Interface)是一种同步串行通信总线,它在微控制器和外设之间传输数据。GD32系列微控制器通过SPI接口与外设(如传感器、存储器等)进行数据交互。为了提高数据传输效率,GD32系列微控制器还支持DMA(Direct Memory Access)技术。 DMA是一种无需CPU介入的数据传输方式,通过配置DMA控制器,可以实现在SPI接口和内存之间直接传输数据。在SPI DMA通信中,可以通过配置GD32DMA控制器,实现SPI数据的输入输出。具体流程如下: 1. 配置SPI接口:包括设置SPI的工作模式(主从模式)、数据位宽、传输速度等参数。 2. 配置DMA通道:包括设置DMA通道的传输方向、传输数据的长度、传输数据的地址等参数。 3. 开启SPIDMA:使能SPI接口和DMA通道,准备数据传输。 4. 启动DMA传输:通过触发信号(例如SPI中断)启动DMA传输,DMA控制器将根据配置的参数自动进行数据传输。 5. 数据传输完成:当DMA传输完成时,触发相应的中断或通过检测标志位完成数据传输的判断。 6. 数据处理:根据需要,对传输的数据进行处理,例如存储、计算、显示等。 7. 重复上述步骤:如果还有需要传输的数据,可以重复上述步骤进行数据传输。 通过使用SPI DMA通信,可以降低CPU的负担,提高系统的并行处理能力,并加快数据传输速度。GD32微控制器提供了相应的库函数和例程,方便开发者进行SPI DMA通信的配置和编程,实现更高效的数据交互。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bourne76

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值