GD32F450串口空闲中断加DMA接收不定长数组

串口初始化

typedef struct  
{  
	uint8_t  RX_flag;        //IDLE receive flag
	uint16_t RX_Size;          //receive length
	uint8_t  RX_pData[RX_LEN]; //DMA receive buffer
}USART_RECEIVETYPE; 

... ...


USART_RECEIVETYPE usart0;

void gd_eval_com_init(uint32_t com)
{
    dma_single_data_parameter_struct dma_init_struct;
	
	
    /* enable GPIO clock */
    uint32_t COM_ID;
    if(EVAL_COM1 == com)
    {
        COM_ID = 0U;
    }

    rcu_periph_clock_enable( EVAL_COM_GPIO_CLK);

    /* enable USART clock */
    rcu_periph_clock_enable(COM_CLK[COM_ID]);

    /* connect port to USARTx_Tx */
    gpio_af_set(EVAL_COM_GPIO_PORT, EVAL_COM_AF, COM_TX_PIN[COM_ID]);

    /* connect port to USARTx_Rx */
    gpio_af_set(EVAL_COM_GPIO_PORT, EVAL_COM_AF, COM_RX_PIN[COM_ID]);

    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(EVAL_COM_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP,COM_TX_PIN[COM_ID]);
    gpio_output_options_set(EVAL_COM_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,COM_TX_PIN[COM_ID]);

    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(EVAL_COM_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP,COM_RX_PIN[COM_ID]);
    gpio_output_options_set(EVAL_COM_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,COM_RX_PIN[COM_ID]);

    /* USART configure */
    usart_deinit(com);
    usart_baudrate_set(com,115200U);
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_enable(USART0);
	
	
        /* deinitialize DMA channel2 (USART0 rx) */
		rcu_periph_clock_enable(RCU_DMA1);
        dma_deinit(DMA1, DMA_CH2);
        dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
        dma_init_struct.memory0_addr = (uint32_t)usart0.RX_pData;
        dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
        dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT;
        dma_init_struct.number = sizeof(usart0.RX_pData);
        dma_init_struct.periph_addr = USART0_DATA_ADDRESS;
        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(DMA1, DMA_CH2, dma_init_struct);
        /* configure DMA mode */
        dma_circulation_disable(DMA1, DMA_CH2);
        dma_channel_subperipheral_select(DMA1, DMA_CH2, DMA_SUBPERI4);
        /* enable DMA channel2 */
        dma_channel_enable(DMA1, DMA_CH2);

		usart_dma_receive_config(USART0, USART_DENR_ENABLE);	/* USART0 DMA接收模式开启 */
		nvic_irq_enable(USART0_IRQn, 0, 0);		/* USART中断设置,抢占优先级0,子优先级0 */
		usart_interrupt_enable(USART0, USART_INTEN_IDLEIE);			/* 使能USART0空闲中断 */


        /* wait DMA channel transfer complete */
        //while(RESET == dma_flag_get(DMA1, DMA_CH2, DMA_INTF_FTFIF));
        //printf("\n\r%s\n\r", usart0.RX_pData);	
}

中断中处理:

/* 串口0中断服务程序 */
void USART0_IRQHandler(void)	
{
    if(RESET != usart_interrupt_flag_get(USART0, USART_INT_IDLEIE) &&
		RESET != usart_flag_get(USART0, USART_FLAG_IDLEF)) //空闲中断
	{
		usart_flag_clear(USART0,USART_FLAG_IDLEF);	/* 清除空闲中断标志位 */
		usart_data_receive(USART0);								/* 清除接收完成标志位 */
		dma_channel_disable(DMA0, DMA_CH2);						/* 关闭DMA传输 */
		usart0.RX_flag = 1;
		usart0.RX_Size = sizeof(usart0.RX_pData) - dma_transfer_number_get(DMA0,DMA_CH2);
		//memcpy(rx0_date_buf,dma_buffer,USART_RX_NUM); /* 转存数据到待处理数据缓冲区*/
		//rx0_date_buf[USART_RX_NUM] = '\0';	/* 添加字符串结束符 */
		
		dma_deinit(DMA1, DMA_CH2);
		dma_init_struct.memory0_addr = (uint32_t)usart0.RX_pData;
		dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
		dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT;
		dma_init_struct.number = sizeof(usart0.RX_pData);
		dma_init_struct.periph_addr = USART0_DATA_ADDRESS;
		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(DMA1, DMA_CH2, dma_init_struct);
		/* configure DMA mode */
		dma_circulation_disable(DMA1, DMA_CH2);
		dma_channel_subperipheral_select(DMA1, DMA_CH2, DMA_SUBPERI4);
		/* enable DMA channel2 */
		dma_channel_enable(DMA1, DMA_CH2);
    }
}

 

你可能感兴趣的:(STM32)