GD32F303 SPI DMA 参考程序
时间: 2023-11-08 18:05:21 浏览: 88
以下是一个基本的SPI DMA参考程序,使用GD32F303 MCU和ST固件库:
```c
#include "gd32f30x.h"
#define SPIx SPI1
#define SPIx_CLK RCU_SPI1
#define SPIx_APBxClock RCU_APB2
#define SPIx_GPIO_APBxClock RCU_GPIOA
#define SPIx_GPIO GPIOA
#define SPIx_PIN_NSS GPIO_PIN_4
#define SPIx_PIN_SCK GPIO_PIN_5
#define SPIx_PIN_MISO GPIO_PIN_6
#define SPIx_PIN_MOSI GPIO_PIN_7
#define SPIx_CS_LOW() gpio_bit_reset(SPIx_GPIO, SPIx_PIN_NSS)
#define SPIx_CS_HIGH() gpio_bit_set(SPIx_GPIO, SPIx_PIN_NSS)
#define DMAx_CLK RCU_DMA0
#define DMAx_CHANNEL DMA_CH2
#define DMAx_CHANNEL_IRQ DMA0_Channel2_IRQn
#define DMAx_CHANNEL_IRQHANDLER DMA0_Channel2_IRQHandler
#define BUFFER_SIZE 256
uint8_t send_buffer[BUFFER_SIZE];
uint8_t receive_buffer[BUFFER_SIZE];
void spi_gpio_init(void)
{
/* enable SPI GPIO clock */
rcu_periph_clock_enable(SPIx_GPIO_APBxClock);
/* configure SPI NSS/CLK/MISO/MOSI GPIO port */
gpio_init(SPIx_GPIO, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SPIx_PIN_NSS);
gpio_init(SPIx_GPIO, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SPIx_PIN_SCK);
gpio_init(SPIx_GPIO, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SPIx_PIN_MISO);
gpio_init(SPIx_GPIO, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SPIx_PIN_MOSI);
/* SPI NSS output high */
gpio_bit_set(SPIx_GPIO, SPIx_PIN_NSS);
}
void spi_dma_init(void)
{
/* enable DMA clock */
rcu_periph_clock_enable(DMAx_CLK);
/* initialize DMA channel */
dma_deinit(DMAx_CHANNEL);
dma_struct_para_init(&dma_init_struct);
/* DMA channel configuration */
dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
dma_init_struct.memory_addr = (uint32_t)send_buffer;
dma_init_struct.memory_inc = DMA_MEMORY_INC_ENABLE;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.number = BUFFER_SIZE;
dma_init_struct.periph_addr = (uint32_t)&SPIx->DR;
dma_init_struct.periph_inc = DMA_PERIPH_INC_DISABLE;
dma_init_struct.periph_width = DMA_PERIPH_WIDTH_8BIT;
dma_init_struct.priority = DMA_PRIORITY_HIGH;
dma_init(DMAx_CHANNEL, dma_init_struct);
/* enable DMA channel transfer complete interrupt */
dma_interrupt_enable(DMAx_CHANNEL, DMA_INT_FTF);
nvic_irq_enable(DMAx_CHANNEL_IRQ, 0, 0);
}
void spi_init(void)
{
spi_parameter_struct spi_init_struct;
/* enable SPI clock */
rcu_periph_clock_enable(SPIx_CLK);
/* SPI parameter configuration */
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
spi_init_struct.device_mode = SPI_MASTER;
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
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_8;
spi_init_struct.endian = SPI_ENDIAN_MSB;
spi_init(SPIx, &spi_init_struct);
/* enable SPI DMA */
spi_dma_enable(SPIx, SPI_DMA_TRANSMIT);
}
void dma_transfer_complete_handler(void)
{
/* disable DMA channel */
dma_channel_disable(DMAx_CHANNEL);
/* wait until SPI is not busy */
while (SET == spi_i2s_flag_get(SPIx, SPI_FLAG_BUSY));
/* receive data from SPI */
for (uint16_t i = 0; i < BUFFER_SIZE; i++)
{
/* wait until receive buffer is not empty */
while (RESET == spi_i2s_flag_get(SPIx, SPI_FLAG_RNE));
receive_buffer[i] = spi_i2s_data_receive(SPIx);
}
/* do something with received data */
/* re-enable DMA channel */
dma_channel_enable(DMAx_CHANNEL);
}
int main(void)
{
/* initialize SPI GPIO and DMA */
spi_gpio_init();
spi_dma_init();
/* initialize SPI */
spi_init();
/* fill send buffer with data */
for (uint16_t i = 0; i < BUFFER_SIZE; i++)
{
send_buffer[i] = i;
}
/* enable DMA channel */
dma_channel_enable(DMAx_CHANNEL);
while (1)
{
/* do something */
}
}
/* DMA interrupt handler */
void DMAx_CHANNEL_IRQHANDLER(void)
{
if (dma_interrupt_flag_get(DMAx_CHANNEL, DMA_INT_FLAG_FTF))
{
dma_interrupt_flag_clear(DMAx_CHANNEL, DMA_INT_FLAG_FTF);
dma_transfer_complete_handler();
}
}
```
在这个例子中,我们使用SPI1作为主设备,使用DMA2通道2将数据发送到SPI,然后等待接收数据。在发送数据之前,我们填充了一个缓冲区,然后启用DMA通道并等待传输完成。一旦传输完成,我们从SPI接收数据,并将它们存储在另一个缓冲区中。在实际的应用程序中,您可以根据需要调整缓冲区的大小和填充数据的方式,以及对接收到的数据执行的操作。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)