- #include "gd32f30x.h"
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
-
-
- void RCU_config(void)
- {
- rcu_periph_clock_enable(RCU_GPIOA);
- rcu_periph_clock_enable(RCU_GPIOB);
- rcu_periph_clock_enable(RCU_USART0);
- rcu_periph_clock_enable(RCU_DMA0);
- }
-
-
- void NVIC_config(void)
- {
- nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
- nvic_irq_enable(USART0_IRQn,1,0);
- }
-
-
- void GPIO_config(void)
- {
- //PA9 USART0_Tx
- gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
- //PA10 USART0_Rx
- gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
- }
-
- #define USART0_DMA_TXBUF_SIZE 100
- #define USART0_DMA_RXBUF_SIZE 100
- uint8_t USART0_DMA_txbuf[USART0_DMA_TXBUF_SIZE];
- uint8_t USART0_DMA_rxbuf[USART0_DMA_RXBUF_SIZE];
-
- void USART0_config(void)
- {
- usart_deinit(USART0);
- usart_baudrate_set(USART0, 115200U);
-
- //--接收超时设置
- usart_receiver_timeout_threshold_config(USART0,100);
- usart_interrupt_enable(USART0,USART_INT_RT);
- usart_receiver_timeout_enable(USART0);
-
- //=====配置USART使用的DMA通道======
- //USART0_TX:DMA0_CH3
- dma_parameter_struct dma_init_struct; //DMA初始化结构体
- dma_deinit(DMA0, DMA_CH3); //复位DMA通道为默认配置
- dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; //传输方向
- dma_init_struct.memory_addr = (uint32_t)USART0_DMA_txbuf; //存储器基地址
- dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; //增量式存储器地址生成模式
- dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; //存储器单个数据宽度
- dma_init_struct.number = 0; //传输长度
- dma_init_struct.periph_addr = (uint32_t)&(USART_DATA(USART0)); //外设基地址(寄存器地址)
- dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; //增量式外设地址生成模式
- dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; //外设单个数据宽度
- dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; //通道的优先级
- dma_init(DMA0, DMA_CH3, &dma_init_struct); //进行配置
- dma_circulation_disable(DMA0, DMA_CH3); //配置循环传输模式(单次模式和循环模式)
- //dma_interrupt_enable(DMA0,DMA_CH3,DMA_INT_FTF); //DMA中断使能
- //dma_channel_enable(DMA0, DMA_CH3); //使能DMA通道
-
-
- //USART0_RX:DMA0_CH4
- dma_deinit(DMA0, DMA_CH4); //复位DMA通道为默认配置
- dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; //传输方向
- dma_init_struct.memory_addr = (uint32_t)USART0_DMA_rxbuf; //存储器基地址
- dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; //增量式存储器地址生成模式
- dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; //存储器单个数据宽度
- dma_init_struct.number = USART0_DMA_RXBUF_SIZE; //传输长度
- dma_init_struct.periph_addr = (uint32_t)&(USART_DATA(USART0)); //外设基地址(寄存器地址)
- dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; //增量式外设地址生成模式
- dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; //外设单个数据宽度
- dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH; //通道的优先级
- dma_init(DMA0, DMA_CH4, &dma_init_struct); //进行配置
- dma_circulation_enable(DMA0, DMA_CH4); //配置循环传输模式(单次模式和循环模式)
- //dma_interrupt_enable(DMA0,DMA_CH4,DMA_INT_FTF); //DMA中断使能
- dma_channel_enable(DMA0, DMA_CH4); //使能DMA通道
-
- //=====使能串口的DMA发送和接收=====
- usart_dma_transmit_config(USART0, USART_DENT_ENABLE); //使能串口的DMA发送
- usart_dma_receive_config(USART0,USART_DENR_ENABLE); //使能串口的DMA接收
-
-
- usart_receive_config(USART0, USART_RECEIVE_ENABLE);
- usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
- usart_enable(USART0);
-
- }
-
-
- void USART0_printf(const char*format , ...)
- {
- int tx_len;
- va_list args;
-
- //如果dma传输通道是使能的,且传输没完成
- while((DMA_CHCTL(DMA0,DMA_CH3)&0x01) && (!dma_flag_get(DMA0,DMA_CH3,DMA_FLAG_FTF))); //等待DMA传输完成
- dma_flag_clear(DMA0,DMA_CH3,DMA_FLAG_FTF); //清除传输完成标志
-
- va_start(args,format);
- tx_len = vsnprintf((char*)USART0_DMA_txbuf,USART0_DMA_TXBUF_SIZE,format,args);
- va_end(args);
-
- if(tx_len>0)
- {
- dma_channel_disable(DMA0,DMA_CH3); //关闭DMA通道,这样才能设置传输长度
- dma_transfer_number_config(DMA0,DMA_CH3,tx_len); //设置本次DMA传输长度
- dma_channel_enable(DMA0,DMA_CH3); //使能USART0_TX使用的DMA通道,开始DMA传输
- }
- }
-
-
- volatile uint32_t USART0_get_msg=0;
- volatile uint32_t USART0_rear=0;
- volatile uint32_t USART0_front=0;
-
- int main(void)
- {
- RCU_config();
- NVIC_config();
- GPIO_config();
- USART0_config();
-
-
- while(1)
- {
- if(USART0_get_msg)
- {
- USART0_get_msg=0;
-
- uint32_t len = (USART0_DMA_RXBUF_SIZE - USART0_front + USART0_rear)%USART0_DMA_RXBUF_SIZE;//本次消息长度
- USART0_printf("\nlen=%u:",len);
- //打印出收到的字符
- for(uint32_t i=0;i<len;i++)
- {
- USART0_printf("[%u]%c ",i,USART0_DMA_rxbuf[USART0_front]); //处理第i个字节
- USART0_front = (USART0_front+1)%USART0_DMA_RXBUF_SIZE; //更新front指针
- }
-
- }
-
- }
- }
-
-
- void USART0_IRQHandler(void)
- {
- //接收超时中断(也可以使用IDLE中断实现)
- if(usart_interrupt_flag_get(USART0,USART_INT_FLAG_RT))
- {
- //清除中断标志
- usart_interrupt_flag_clear(USART0,USART_INT_FLAG_RT);
- //计算rear的值
- USART0_rear = USART0_DMA_RXBUF_SIZE - dma_transfer_number_get(DMA0,DMA_CH4);
- //通知main收到了一包数据
- USART0_get_msg=1;
- }
-
- }