DMA 全称Direct Memory Access,即直接存储器访问。
DMA传输将数据从一个地址空间复制到另一个地址空间。当CPU初始化这个传输动作,传输动作本身是由DMA控制器来实现和完成的。
GD32F450有两个DMA控制器(DMA2只存在于大容量产品中),DMA1和DMA2都有8个通道,每个通道专门用来管理来自于一个或者多个外设对存储器的访问请求。还有一个仲裁器来协调各个DMA请求的优先权。
串口DMA作用是减轻CPU负担开销。
GD32串口空闲中断是指当串口接收缓冲区中没有数据时,会触发空闲中断。在空闲中断中,我们可以将接收数据搬运至接收二级缓存区中。使用空闲中断可以在保证数据完整性的同时提高串口接收数据的效率。
1.H文件
#ifndef _MODEL_CONSOLE_INIT_H
#define _MODEL_CONSOLE_INIT_H
#include "gd32f4xx.h"
#define MAX_SIZE_OF_USART0_RX_BUFFER 512 // 接收缓存区大小
#define MAX_SIZE_OF_USART0_TX_BUFFER 512 // 接收缓存区大小
extern unsigned char usart0_rx_DataBuf[MAX_SIZE_OF_USART0_RX_BUFFER];
void model_console_init(void);
void model_console_init_dma_config(void);
void model_console_Send_Buff(unsigned char* pdata, unsigned short usLen);
int fputc(int ch, FILE *f);
#endif
2.C文件
#include "main.h"
#include "model_console_init.h"
#include "model_console_buff.h"
#include "model_common_frame.h"
#include "gd32f4xx_dma.h"
#include "gd32f4xx_usart.h"
#include "gd32f4xx_rcu.h"
#include "gd32f4xx_gpio.h"
unsigned char usart0_rx_DataBuf[MAX_SIZE_OF_USART0_RX_BUFFER] = {0};
#define BSP_USART_TX_RCU RCU_GPIOA
#define BSP_USART_RX_RCU RCU_GPIOA
#define BSP_USART_RCU RCU_USART0
#define BSP_USART_TX_PORT GPIOA
#define BSP_USART_RX_PORT GPIOA
#define BSP_USART_AF GPIO_AF_7
#define BSP_USART_TX_PIN GPIO_PIN_9
#define BSP_USART_RX_PIN GPIO_PIN_10
#define BSP_USART USART0
#define BSP_USART_IRQ USART0_IRQn
#define BSP_USART_BAUD 115200
static void model_console_init_usart_gpio_config(void)
{
/* 开启时钟 */
rcu_periph_clock_enable(BSP_USART_TX_RCU);
rcu_periph_clock_enable(BSP_USART_RX_RCU);
rcu_periph_clock_enable(BSP_USART_RCU);
/* 配置GPIO复用功能 */
gpio_af_set(BSP_USART_TX_PORT,BSP_USART_AF,BSP_USART_TX_PIN);
gpio_af_set(BSP_USART_RX_PORT,BSP_USART_AF,BSP_USART_RX_PIN);
/* 配置GPIO的模式 */
/* 配置TX为复用模式 上拉模式 */
gpio_mode_set(BSP_USART_TX_PORT,GPIO_MODE_AF,GPIO_PUPD_PULLUP,BSP_USART_TX_PIN);
gpio_mode_set(BSP_USART_RX_PORT, GPIO_MODE_AF,GPIO_PUPD_PULLUP,BSP_USART_RX_PIN);
/* 配置TX为推挽输出 50MHZ */
gpio_output_options_set(BSP_USART_TX_PORT,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,BSP_USART_TX_PIN);
gpio_output_options_set(BSP_USART_RX_PORT,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, BSP_USART_RX_PIN);
/* 配置串口的参数 */
usart_deinit(BSP_USART);
usart_baudrate_set(BSP_USART,BSP_USART_BAUD);
usart_parity_config(BSP_USART,USART_PM_NONE);
usart_word_length_set(BSP_USART,USART_WL_8BIT);
usart_stop_bit_set(BSP_USART,USART_STB_1BIT);
/* 使能串口 */
usart_enable(BSP_USART);
usart_transmit_config(BSP_USART,USART_TRANSMIT_ENABLE);
usart_receive_config(BSP_USART,USART_RECEIVE_ENABLE);
nvic_irq_enable(BSP_USART_IRQ, 2, 2);
// usart_interrupt_enable(BSP_USART,USART_INT_RBNE);
usart_interrupt_enable(BSP_USART,USART_INT_IDLE);
}
#define BSP_DMA_RCU RCU_DMA1
#define BSP_DMA DMA1
#define BSP_DMA_CH DMA_CH2
#define BSP_DMA_CH_IRQ DMA1_Channel2_IRQn
#define BSP_DMA_CH_IRQ_HANDLER DMA1_Channel2_IRQHandler
void model_console_init_dma_config(void)
{
dma_single_data_parameter_struct dma_init_struct;
rcu_periph_clock_enable(BSP_DMA_RCU);
dma_interrupt_flag_clear(BSP_DMA, BSP_DMA_CH, DMA_INTC_FEEIFC|DMA_INTC_SDEIFC|DMA_INTC_TAEIFC|DMA_INTC_HTFIFC|DMA_INTC_FTFIFC);//中断标志位清除
dma_deinit(BSP_DMA,BSP_DMA_CH);
dma_init_struct.periph_addr = (uint32_t)&USART_DATA(BSP_USART);
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.memory0_addr = (uint32_t)usart0_rx_DataBuf;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE;
dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
dma_init_struct.number = MAX_SIZE_OF_USART0_RX_BUFFER;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_single_data_mode_init(BSP_DMA,BSP_DMA_CH,&dma_init_struct);
dma_channel_subperipheral_select(BSP_DMA,BSP_DMA_CH,DMA_SUBPERI4);
dma_channel_enable(BSP_DMA,BSP_DMA_CH);
// dma_interrupt_enable(BSP_DMA,BSP_DMA_CH,DMA_CHXCTL_FTFIE);
// nvic_irq_enable(BSP_DMA_CH_IRQ, 2, 1);
usart_dma_receive_config(BSP_USART,USART_DENR_ENABLE);
}
void model_console_init(void)
{
model_console_init_usart_gpio_config();
model_console_init_dma_config();
}
void model_console_Send_Buff(unsigned char* pdata, unsigned short usLen) //串口输出字符串
{
for(unsigned int i=0;i