- #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;
- /* 重定向printf函数 */
- 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)
- {
- //UART0 DMA0-CH4
- //UART1 DMA0-CH5
- //UART2-DMA0-CH2
- //UART3-DMA1-CH2
- 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;
- }
- /*!
- \brief 初始化串口涉及的时钟和gpio gpio USART/UART
- \param[in] usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)
- \param[out] none
- \retval none
- */
- void bsp_uart_gpio_rcu_init(uint32_t usart_periph)
- {
- /*********************串口0********************/
- if(usart_periph == USART0)
- {
- /* 使能串口时钟 */
- rcu_periph_clock_enable(RCU_USART0);
- /* 使能gpio时钟 */
- rcu_periph_clock_enable(RCU_GPIOA);
- /* gpio IO 初始化发送引脚 */
- 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);
- }
- /*********************串口0********************/
- /*********************串口1********************/
- else if(usart_periph == USART1)
- {
- /* 使能串口时钟 */
- rcu_periph_clock_enable(RCU_USART1);
- /* 使能gpio时钟 */
- rcu_periph_clock_enable(RCU_GPIOA);
- /* gpio IO 初始化发送引脚 */
- 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);
- }
- /*********************串口1********************/
- /*********************串口2********************/
- else if(usart_periph == USART2)
- {
- /* 使能串口时钟 */
- rcu_periph_clock_enable(RCU_USART2);
- /* 使能gpio时钟 */
- rcu_periph_clock_enable(RCU_GPIOB);
- /* gpio IO 初始化发送引脚 */
- 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);
- }
- /*********************串口2********************/
- /*********************串口3********************/
- else if(usart_periph == UART3)
- {
- /* 使能串口时钟 */
- rcu_periph_clock_enable(RCU_UART3);
- /* 使能gpio时钟 */
- rcu_periph_clock_enable(RCU_GPIOC);
- /* gpio IO 初始化发送引脚 */
- 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);
- }
- /*********************串口3********************/
- /*********************串口4********************/
- else if(usart_periph == UART4)
- {
- /* 使能串口时钟 */
- rcu_periph_clock_enable(RCU_UART4);
- }
- /*********************串口4********************/
- }
- /*基本初始化函数*/
- void bsp_uart_usart_base_init(uint32_t usart_periph)
- {
- //外设的gpio初始化和时钟初始化
- bsp_uart_gpio_rcu_init(usart_periph);
- /* USART configure 串口参数初始化 */
- 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);//空闲中断
- }
- /*
- 功能:DMA 中断接收数据,uart5 不可以使用dma传输数据
- hope_len:希望接收的数据个数
- circulation:是否使用连续模式
- */
- int bsp_uart_dma_nvic_init(uart_dam_t *puart_dma)
- {
- dma_parameter_struct dma_init_struct;
- if(puart_dma == NULL)
- {
- return 0;
- }
- /* enable DMA0 clock 使能DMA0 的时钟*/
- 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;//数据长度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优先级
- 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 DMA0 串口0DMA 数据接收使能 */
- usart_dma_receive_config(puart_dma->usart_periph, USART_DENR_ENABLE);
- /* enable DMA0 串口0 DMA 接收完成中断使能 */
- dma_interrupt_enable(puart_dma->dma_periph, puart_dma->dma_channelx, DMA_INT_FTF);
- /* enable DMA0 启用指定的DMA通道*/
- dma_channel_enable(puart_dma->dma_periph, puart_dma->dma_channelx);
- return 1;
- }
- /*
- 禁止中断和DMA
- */
- void bsp_uart0_init_idle_it_disable()
- {
- //禁止中断
- nvic_irq_disable(USART0_IRQn);
- usart_interrupt_disable(USART0, USART_INT_IDLE);//空闲中断
- //禁止DMA
- dma_channel_disable(DMA0, DMA_CH4);
- }
- /*
- 串口0中断处理函数
- */
- 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,重新计算剩余未传输数量
- 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);
- }
- }
- /*
- 串口3中断处理函数
- */
- 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,重新计算剩余未传输数量
- 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);
- }
- }
- /*
- 串口2中断处理函数
- */
- 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,重新计算剩余未传输数量
- 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);
- }
- }
- /*
- 串口3中断处理函数
- */
- 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,重新计算剩余未传输数量
- 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);
- }
- }
- /*串口0dma*/
- 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中断标记
- 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;
- }
- }
- /*串口1 dma*/
- 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中断标记
- 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;
- }
- }
- /*串口2 dma*/
- 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中断标记
- 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;
- }
- }
- /*串口3 dma*/
- 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中断标记
- 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;
- }
- }