由于需求用到GD32 SPI,
故做相关实验记录分享,本实验为 SPI DMA 发送与接收 16bit 数据, GD32 相关配置如下
GD32 F30x系列 DMA配置如下
SPI DMA 发:使用SPI0,对应的DMA为0 Channel 2。
注意打开 对应 DMA 与 SPI 相关时钟, DMA write 使用时需要先拉低 NSS,发送结束,拉高NSS文章来源:https://www.toymoban.com/news/detail-535920.html
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文章来源地址https://www.toymoban.com/news/detail-535920.html
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收发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!