头文件
#ifndef _UART_H_
#define _UART_H_
#include "stdint.h"
#include "gd32f30x.h"
#define CACHE_NUM 128
typedef void (*recv_hanled)(uint8_t *data, uint16_t len);
typedef struct
{
uint32_t usart_periph;
uint32_t dma_periph;
dma_channel_enum dma_channelx;
uint8_t dma_nvic_irq;
uint8_t uart_nvic_irq;
uint8_t dma_or_idle;
uint16_t data_num;
uint8_t uart_rx_buffers[CACHE_NUM];
recv_hanled hanled_fun;
} uart_dam_t;
void bsp_uart_gpio_rcu_init(uint32_t usart_periph);
void bsp_uart_usart_base_init(uint32_t usart_periph);
uart_dam_t * init_uart_dma_struct(uint32_t usart_periph);
void bsp_uart_enable_uart_interrupt(uart_dam_t *puart_dma);
int bsp_uart_dma_nvic_init(uart_dam_t *puart_dma);
int bsp_uart_register_handle(uart_dam_t *puart_dma, recv_hanled hanled_fun);
void bsp_uart_dma_procees(uint32_t tick);
#endif
源文件
#include "uart.h"
#include "stdio.h"
#include "gd32f30x.h"
uart_dam_t uart0_dma;
uart_dam_t uart1_dma;
uart_dam_t uart2_dma;
uart_dam_t uart3_dma;
volatile uint16_t uart_rxcount[5];
volatile uint8_t idle_or_full = 0;
int fputc(int ch, FILE *f)
{
int cnt = 1000;
usart_data_transmit(USART0, (uint8_t)ch);
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE) && cnt--);
usart_data_transmit(USART1, (uint8_t)ch);
cnt = 1000;
while(RESET == usart_flag_get(USART1, USART_FLAG_TBE) && cnt--);
return ch;
}
uart_dam_t * init_uart_dma_struct(uint32_t usart_periph)
{
uart_dam_t *puart_dma = NULL;
if(usart_periph == USART0)
{
puart_dma = &uart0_dma;
puart_dma->dma_periph = DMA0;
puart_dma->dma_channelx = DMA_CH4;
puart_dma->dma_nvic_irq = DMA0_Channel4_IRQn;
puart_dma->uart_nvic_irq = USART0_IRQn;
}
else if(usart_periph == USART1)
{
puart_dma = &uart1_dma;
puart_dma->dma_periph = DMA0;
puart_dma->dma_channelx = DMA_CH5;
puart_dma->dma_nvic_irq = DMA0_Channel5_IRQn;
puart_dma->uart_nvic_irq = USART1_IRQn;
}
else if(usart_periph == USART2)
{
puart_dma = &uart2_dma;
puart_dma->dma_periph = DMA0;
puart_dma->dma_channelx = DMA_CH2;
puart_dma->dma_nvic_irq = DMA0_Channel2_IRQn;
puart_dma->uart_nvic_irq = USART2_IRQn;
}
else if(usart_periph == UART3)
{
puart_dma = &uart3_dma;
puart_dma->dma_periph = DMA1;
puart_dma->dma_channelx = DMA_CH2;
puart_dma->dma_nvic_irq = DMA0_Channel2_IRQn;
puart_dma->uart_nvic_irq = UART3_IRQn;
}
puart_dma->usart_periph = usart_periph;
return puart_dma;
}
void bsp_uart_gpio_rcu_init(uint32_t usart_periph)
{
if(usart_periph == USART0)
{
rcu_periph_clock_enable(RCU_USART0);
rcu_periph_clock_enable(RCU_GPIOA);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
}
else if(usart_periph == USART1)
{
rcu_periph_clock_enable(RCU_USART1);
rcu_periph_clock_enable(RCU_GPIOA);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
}
else if(usart_periph == USART2)
{
rcu_periph_clock_enable(RCU_USART2);
rcu_periph_clock_enable(RCU_GPIOB);
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
}
else if(usart_periph == UART3)
{
rcu_periph_clock_enable(RCU_UART3);
rcu_periph_clock_enable(RCU_GPIOC);
gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
}
else if(usart_periph == UART4)
{
rcu_periph_clock_enable(RCU_UART4);
}
}
void bsp_uart_usart_base_init(uint32_t usart_periph)
{
bsp_uart_gpio_rcu_init(usart_periph);
usart_deinit(usart_periph);
usart_baudrate_set(usart_periph, 115200U);
usart_word_length_set(usart_periph, USART_WL_8BIT);
usart_stop_bit_set(usart_periph, USART_STB_1BIT);
usart_parity_config(usart_periph, USART_PM_NONE);
usart_hardware_flow_rts_config(usart_periph, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(usart_periph, USART_CTS_DISABLE);
usart_receive_config(usart_periph, USART_RECEIVE_ENABLE);
usart_transmit_config(usart_periph, USART_TRANSMIT_ENABLE);
usart_enable(usart_periph);
}
void bsp_uart_enable_uart_interrupt(uart_dam_t *puart_dma)
{
nvic_irq_enable(puart_dma->uart_nvic_irq, 1, 1);
usart_interrupt_flag_clear(puart_dma->usart_periph, USART_INT_FLAG_IDLE);
usart_interrupt_enable(puart_dma->usart_periph, USART_INT_IDLE);
}
int bsp_uart_dma_nvic_init(uart_dam_t *puart_dma)
{
dma_parameter_struct dma_init_struct;
if(puart_dma == NULL)
{
return 0;
}
if(puart_dma->usart_periph == USART0 ||
puart_dma->usart_periph == USART1 ||
puart_dma->usart_periph == USART2)
{
rcu_periph_clock_enable(RCU_DMA0);
}
else if(puart_dma->usart_periph == UART3)
{
rcu_periph_clock_enable(RCU_DMA1);
}
nvic_irq_enable(puart_dma->dma_nvic_irq, 0, 1);
dma_deinit(puart_dma->dma_periph, puart_dma->dma_channelx);
dma_struct_para_init(&dma_init_struct);
dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
dma_init_struct.memory_addr = (uint32_t)puart_dma->uart_rx_buffers;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
dma_init_struct.number = CACHE_NUM;
#define USART0_DATA_ADDRESS ((uint32_t)&USART_DATA(USART0))
dma_init_struct.periph_addr = USART0_DATA_ADDRESS;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.memory_width = DMA_PERIPHERAL_WIDTH_8BIT;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_init(puart_dma->dma_periph, puart_dma->dma_channelx, &dma_init_struct);
dma_circulation_enable(puart_dma->dma_periph, puart_dma->dma_channelx);
dma_memory_to_memory_disable(puart_dma->dma_periph, puart_dma->dma_channelx);
usart_dma_receive_config(puart_dma->usart_periph, USART_DENR_ENABLE);
dma_interrupt_enable(puart_dma->dma_periph, puart_dma->dma_channelx, DMA_INT_FTF);
dma_channel_enable(puart_dma->dma_periph, puart_dma->dma_channelx);
return 1;
}
void bsp_uart0_init_idle_it_disable()
{
nvic_irq_disable(USART0_IRQn);
usart_interrupt_disable(USART0, USART_INT_IDLE);
dma_channel_disable(DMA0, DMA_CH4);
}
void USART0_IRQHandler(void)
{
uart_dam_t *p_uart_dma = &uart0_dma;
if(RESET != usart_interrupt_flag_get(p_uart_dma->usart_periph, USART_INT_FLAG_IDLE))
{
usart_data_receive(p_uart_dma->usart_periph);
p_uart_dma->data_num = CACHE_NUM - dma_transfer_number_get(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
p_uart_dma->dma_or_idle = 1;
dma_channel_disable(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
DMA_CHCNT(p_uart_dma->dma_periph, p_uart_dma->dma_channelx) = CACHE_NUM;
dma_channel_enable(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
}
}
void USART1_IRQHandler(void)
{
uart_dam_t *p_uart_dma = &uart1_dma;
if(RESET != usart_interrupt_flag_get(p_uart_dma->usart_periph, USART_INT_FLAG_IDLE))
{
usart_data_receive(p_uart_dma->usart_periph);
p_uart_dma->data_num = CACHE_NUM - dma_transfer_number_get(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
p_uart_dma->dma_or_idle = 1;
dma_channel_disable(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
DMA_CHCNT(p_uart_dma->dma_periph, p_uart_dma->dma_channelx) = CACHE_NUM;
dma_channel_enable(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
}
}
void USART2_IRQHandler(void)
{
uart_dam_t *p_uart_dma = &uart2_dma;
if(RESET != usart_interrupt_flag_get(p_uart_dma->usart_periph, USART_INT_FLAG_IDLE))
{
usart_data_receive(p_uart_dma->usart_periph);
p_uart_dma->data_num = CACHE_NUM - dma_transfer_number_get(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
p_uart_dma->dma_or_idle = 1;
dma_channel_disable(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
DMA_CHCNT(p_uart_dma->dma_periph, p_uart_dma->dma_channelx) = CACHE_NUM;
dma_channel_enable(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
}
}
void UART3_IRQHandler(void)
{
uart_dam_t *p_uart_dma = &uart3_dma;
if(RESET != usart_interrupt_flag_get(p_uart_dma->usart_periph, USART_INT_FLAG_IDLE))
{
usart_data_receive(p_uart_dma->usart_periph);
p_uart_dma->data_num = CACHE_NUM - dma_transfer_number_get(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
p_uart_dma->dma_or_idle = 1;
dma_channel_disable(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
DMA_CHCNT(p_uart_dma->dma_periph, p_uart_dma->dma_channelx) = CACHE_NUM;
dma_channel_enable(p_uart_dma->dma_periph, p_uart_dma->dma_channelx);
}
}
void DMA0_Channel4_IRQHandler(void)
{
uart_dam_t *p_uart_dma = &uart0_dma;
if(dma_interrupt_flag_get(p_uart_dma->dma_periph, p_uart_dma->dma_channelx, DMA_INT_FLAG_FTF))
{
dma_interrupt_flag_clear(p_uart_dma->dma_periph, p_uart_dma->dma_channelx, DMA_INT_FLAG_G);
p_uart_dma->dma_or_idle = SET;
}
}
void DMA0_Channel5_IRQHandler(void)
{
uart_dam_t *p_uart_dma = &uart1_dma;
if(dma_interrupt_flag_get(p_uart_dma->dma_periph, p_uart_dma->dma_channelx, DMA_INT_FLAG_FTF))
{
dma_interrupt_flag_clear(p_uart_dma->dma_periph, p_uart_dma->dma_channelx, DMA_INT_FLAG_G);
p_uart_dma->dma_or_idle = SET;
}
}
void DMA0_Channel2_IRQHandler(void)
{
uart_dam_t *p_uart_dma = &uart2_dma;
if(dma_interrupt_flag_get(p_uart_dma->dma_periph, p_uart_dma->dma_channelx, DMA_INT_FLAG_FTF))
{
dma_interrupt_flag_clear(p_uart_dma->dma_periph, p_uart_dma->dma_channelx, DMA_INT_FLAG_G);
p_uart_dma->dma_or_idle = SET;
}
}
void DMA1_Channel2_IRQHandler(void)
{
uart_dam_t *p_uart_dma = &uart3_dma;
if(dma_interrupt_flag_get(p_uart_dma->dma_periph, p_uart_dma->dma_channelx, DMA_INT_FLAG_FTF))
{
dma_interrupt_flag_clear(p_uart_dma->dma_periph, p_uart_dma->dma_channelx, DMA_INT_FLAG_G);
p_uart_dma->dma_or_idle = SET;
}
}
int bsp_uart_register_handle(uart_dam_t *puart_dma, recv_hanled hanled_fun)
{
puart_dma->hanled_fun = hanled_fun;
}
void bsp_uart_dma_procees(uint32_t tick)
{
if(uart0_dma.dma_or_idle)
{
uart_dam_t *puart_dma = &uart0_dma;
puart_dma->dma_or_idle = 0;
puart_dma->hanled_fun(puart_dma->uart_rx_buffers, puart_dma->data_num);
puart_dma->data_num = 0;
}
else if(uart1_dma.dma_or_idle)
{
uart_dam_t *puart_dma = &uart1_dma;
puart_dma->dma_or_idle = 0;
puart_dma->hanled_fun(puart_dma->uart_rx_buffers, puart_dma->data_num);
puart_dma->data_num = 0;
}
if(uart2_dma.dma_or_idle)
{
uart_dam_t *puart_dma = &uart2_dma;
puart_dma->dma_or_idle = 0;
puart_dma->hanled_fun(puart_dma->uart_rx_buffers, puart_dma->data_num);
puart_dma->data_num = 0;
}
if(uart3_dma.dma_or_idle)
{
uart_dam_t *puart_dma = &uart3_dma;
puart_dma->dma_or_idle = 0;
puart_dma->hanled_fun(puart_dma->uart_rx_buffers, puart_dma->data_num);
puart_dma->data_num = 0;
}
}
测试
#include "gd32f30x.h"
#include "gd32f303_sys.h"
#include "systick.h"
#include "uart.h"
#include "stdio.h"
#include "adc.h"
#include "button.h"
#include "bsp_gpio.h"
#include "at24cxx.h"
void uart0_recv_hanled(uint8_t *data, uint16_t len)
{
printf("read len = %d:", len);
for(int i = 0; i < len; i++)
{
printf("%02x ", (int)data[i]);
}
printf("\r\n");
}
int main(void)
{
systick_config();
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
rcu_periph_clock_enable(RCU_AF);
gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);
bsp_gpio_init();
bsp_uart_gpio_rcu_init(USART0);
bsp_uart_usart_base_init(USART0);
uart_dam_t *uart_dma = init_uart_dma_struct(USART0);
bsp_uart_enable_uart_interrupt(uart_dma);
bsp_uart_dma_nvic_init(uart_dma);
bsp_uart_register_handle(uart_dma, uart0_recv_hanled);
printf("hello gd32\r\n");
BEEP = 0;
while(1)
{
if(tick % 500 == 0)
{
LED0 = !LED0;
LED1 = !LED1;
LED2 = !LED2;
}
bsp_uart_dma_procees(tick);
}
}
# 测试图