GD32F4x 使用串口的空闲中断问题

项目中,需要用到空闲中断去实现变长数据的接收,于是就使用空闲中断去处理。流程如下

  1. 初始化串口
  2. 初始化DMA
  3. 写串口的空闲中断函数
// 初始化串口
void USART2_init()//对外
{
	/* connect port to USARTx_Tx */  	 
	/* connect port to USARTx_Rx */ 
	gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_10);//TX
	gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_11);//RX	 
	/* configure USART Tx as alternate function push-pull */ 
	/* configure USART Rx as alternate function push-pull */  
	gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
	gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_11);

	gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
	gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);

	/* reset USART */
	usart_deinit(USART2);
	/* configure usart baud rate value */
	usart_baudrate_set(USART2, 115200);
	//usart_oversample_config(UART3, USART_OVSMOD_8);
	/* configure usart parity function */
	usart_parity_config(USART2, USART_PM_NONE);
	/* configure usart word length */
	usart_word_length_set(USART2, USART_WL_8BIT);
	/* configure usart stop bit length */
	usart_stop_bit_set(USART2, USART_STB_1BIT);
	/* USART transmit data function */
	usart_transmit_config(USART2, USART_TRANSMIT_ENABLE);
	/* configure USART receiver */
	usart_receive_config(USART2, USART_RECEIVE_ENABLE);
	/* enable usart */
	usart_enable(USART2);

	//usart_interrupt_enable(USART2, USART_INT_RBNE);

	/* DISABLE USART2 DMA Rx request */
	//usart_dma_receive_config(USART2, USART_DENR_DISABLE);
	usart_dma_receive_config(USART2, USART_DENR_ENABLE);

	usart_interrupt_enable(USART2, USART_INT_IDLE);
}
//初始化DMA
void DMA_config(void)
{
    dma_single_data_parameter_struct dma_init_struct;
    /* enable DMA clock */
    rcu_periph_clock_enable(RCU_DMA0);
  
    /* deinitialize DMA channel2 */
    dma_deinit(DMA0, DMA_CH1);
		dma_single_data_para_struct_init(&dma_init_struct);
    dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
    dma_init_struct.memory0_addr = (uint32_t)Update_Package;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
//    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = UPDATE_PACKAGE_SIZE;
    dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_DISABLE;
    dma_init_struct.periph_addr = (uint32_t)&USART_DATA(USART2);
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_single_data_mode_init(DMA0, DMA_CH1, &dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA0, DMA_CH1);			/* 关闭DMA循环模式 */
    dma_channel_subperipheral_select(DMA0, DMA_CH1, DMA_SUBPERI4);
//    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
//    dma_multi_data_mode_init(DMA0, DMA_CH1, &dma_init_struct);
  
    // dma_interrupt_enable(DMA0, DMA_CH1, DMA_CHXCTL_FTFIE);

dma_channel_enable(DMA0, DMA_CH1);
}

// 串口空闲中断处理函数
void USART2_IRQHandler(void)
{
	uint8_t data = 0;
	uint8_t check = 0;


	if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_IDLE)){

		usart_interrupt_flag_clear(USART2, USART_INT_FLAG_IDLE); 	         /* 清除空闲中断标志位 */
		usart_data_receive(USART2);   										 /* 清除接收完成标志位 */
		dma_channel_disable(DMA0, DMA_CH1);									 /* 关闭DMA传输 */
		dma_interrupt_flag_clear(DMA0,DMA_CH1,DMA_INT_FLAG_FTF);             /* 清除DMA中断标志*/

		tmp_size = dma_transfer_number_get(DMA0, DMA_CH1);
		idel_interupt_data_sum = UPDATE_PACKAGE_SIZE - tmp_size;
		memcpy(recved_Package, Update_Package, idel_interupt_data_sum);
 		recved_Package[idel_interupt_data_sum] = '\0';



		send_package_to_target(USART2_Send_Msg, recved_Package, idel_interupt_data_sum);

		// dma_memory_address_config(DMA0, DMA_CH1, false, (uint32_t)Update_Package);
		dma_transfer_number_config(DMA0, DMA_CH1, UPDATE_PACKAGE_SIZE);
		dma_channel_enable(DMA0, DMA_CH1);



	}
}

这样,就可以变长的从串口中获取数据,But,测试发现,只有第一次有数据,然后,每次收到的就是0了,DMA就无法收到串口数据了。

问题所在:

空闲中断的处理中,没有加上 dma_interrupt_flag_clear(DMA0,DMA_CH1,DMA_INT_FLAG_FTF);,没有给DMA中断标志清除,所以导致后面DMA无法收到数据,可以看下面这篇博客,写的很详细,包括如何去找到问题的。

GD32F4串口dma接收问题解决