使用GD32H759,处于cortexm7内核,和STM32H7同一个内核,所以配置基本上相同,由于GD32系列更新,所以工艺更高,发热等等控制更好.GD32官方没有提供类似于STM32的HAL库,只有标准库,同时配置方法与STM32有一点不同.
进入正文,工程结构,本次文章的内容主要集中在SYS文件夹,BSP文件夹的内容可以删除.
思路
在USART接收完成以后,也就是数据没有继续发送时,USART会产生一个IDLE 空闲中断,其标志位为USART_FLAG_IDLE,发生IDLE中断以后,我们可以在其中读取缓冲区,通知接受完成等等,结合DMA功能自动将数据搬运到缓冲区,在IDLE中断中获取数据长度,清除中断标志位,DMA传输标志位,以及开始下一次DMA搬运.
所有我们需要先配置USART的IDLE中断,确认能够进入中断以后编写DMA的参数,在IDLE中启动DMA,当再次发生IDLE中断时,可认为本次串口发送完毕,使用DMA再将数据发送到USART_TD发送寄存器发送出去.
串口配置
首先根据基本的示例代码,配置我们的串口基本参数,USART对应端口自行选择修改.
由于我们需要在IDLE中断中完成数据接收,所以配置串口中断的NVIC.
void USART_Init(uint32_t bound)
{
/* IO 及 时钟配置 */
rcu_periph_clock_enable(USART_TX_GPIO_CLK); /* 使能串口TX脚时钟 */
rcu_periph_clock_enable(USART_RX_GPIO_CLK); /* 使能串口RX脚时钟 */
rcu_periph_clock_enable(RCU_USART1); /* 使能串口时钟 */
USART_RX_DMA_Config();
USART_TX_DMA_Config();
/* 设置USARTx_TX的复用功能选择 */
gpio_af_set(USART_TX_GPIO_PORT, USART_TX_GPIO_AF, USART_TX_GPIO_PIN);
/* 设置USARTx_RX的复用功能选择 */
gpio_af_set(USART_RX_GPIO_PORT, USART_RX_GPIO_AF, USART_RX_GPIO_PIN);
/* USARTx_TX的模式设置 */
gpio_mode_set(USART_TX_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART_TX_GPIO_PIN);
gpio_output_options_set(USART_TX_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, USART_TX_GPIO_PIN);
/* USARTx_RX的模式设置 */
gpio_mode_set(USART_RX_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, USART_RX_GPIO_PIN);
gpio_output_options_set(USART_RX_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, USART_RX_GPIO_PIN);
/* 配置USART的参数 */
usart_deinit(USART1); /* 复位USARTx */
usart_baudrate_set(USART1, bound); /* 设置波特率 */
usart_stop_bit_set(USART1, USART_STB_1BIT); /* 一个停止位 */
usart_word_length_set(USART1, USART_WL_8BIT); /* 字长为8位数据格式 */
usart_parity_config(USART1, USART_PM_NONE); /* 无奇偶校验位 */
usart_transmit_config(USART1, USART_TRANSMIT_ENABLE); /* 使能发送 */
usart_dma_transmit_config(USART1, USART_TRANSMIT_DMA_ENABLE);
usart_receive_config(USART1, USART_RECEIVE_ENABLE); /* 使能接收 */
usart_dma_receive_config(USART1, USART_RECEIVE_DMA_ENABLE);
usart_flag_clear(USART1, USART_FLAG_IDLE); //没啥用
usart_interrupt_enable(USART1, USART_INT_IDLE);
/* 配置NVIC,并设置中断优先级 */
nvic_irq_enable(USART1_IRQn, 3, 3); /* 组2,抢占优先级3,子优先级3 */
usart_enable(USART1); /* 使能串口 */
usart_flag_clear(USART1, USART_FLAG_IDLE); //没啥用
}