[AT32F421] 为什么at32f421 usart1 DMA发送完成没有进入中断

[复制链接]
228|4
transtec 发表于 2025-11-17 21:46 | 显示全部楼层 |阅读模式
本帖最后由 transtec 于 2025-11-17 21:51 编辑

我目前的需求是在新的发送前先检测上次是否发送完成,但主函数中的 if(usart1_tx_dma_status==1)这个一直没有进入。

void DMA1_Channel3_2_IRQHandler(void)
{
    if(dma_interrupt_flag_get(DMA1_FDT2_FLAG))
    {
        usart1_tx_dma_status = 1;
        dma_flag_clear(DMA1_FDT2_FLAG);
        dma_channel_enable(DMA1_CHANNEL2, FALSE);
    }
    else if(dma_interrupt_flag_get(DMA1_FDT3_FLAG))
    {
        usart1_rx_dma_status = 1;
        dma_flag_clear(DMA1_FDT3_FLAG);
        dma_channel_enable(DMA1_CHANNEL3, FALSE);
    }
}



int main(void)
{
    system_clock_config();
    nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
    at32_board_init();
    usart_configuration();
    dma_configuration();

    /* wait dma transmission complete */
//  while((usart1_tx_dma_status == 0) || (usart1_rx_dma_status == 0));

    while(1)
    {

        delay_sec(2);

        at32_led_toggle(LED3);

        if(usart1_tx_dma_status==1)
        {
            usart1_tx_dma_status=0;

            at32_led_toggle(LED2);

            *usart1_tx_buffer = *usart_tx;

            dma_interrupt_enable(DMA1_CHANNEL2, DMA_FDT_INT, TRUE);
        }
    }
}



void usart_configuration(void)
{
    gpio_init_type gpio_init_struct;

    /* enable the usart2 and gpio clock */
    crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);

    /* enable the usart1 and gpio clock */
    crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);

    gpio_default_para_init(&gpio_init_struct);
    /* configure the usart2 tx/rx pin */
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_pins = GPIO_PINS_9 | GPIO_PINS_10;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init(GPIOA, &gpio_init_struct);

    gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE9, GPIO_MUX_1);
    gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE10, GPIO_MUX_1);

    usart_init(USART1, 9600, USART_DATA_8BITS, USART_STOP_1_BIT);
    usart_transmitter_enable(USART1, TRUE);
    usart_receiver_enable(USART1, TRUE);
    usart_dma_transmitter_enable(USART1, TRUE);
    usart_dma_receiver_enable(USART1, TRUE);
    usart_enable(USART1, TRUE);
}

/**
  * @brief  config dma for usart2 and usart1
  * @param  none
  * @retval none
  */
void dma_configuration(void)
{
    dma_init_type dma_init_struct;

    /* enable dma1 clock */
    crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
    /* enable transfer full data interrupt */
    dma_interrupt_enable(DMA1_CHANNEL5, DMA_FDT_INT, TRUE);

    /* dma1 channel5 interrupt nvic init */
    nvic_irq_enable(DMA1_Channel5_4_IRQn, 0, 0);

    /* dma1 channel2 for usart1 tx configuration */
    dma_reset(DMA1_CHANNEL2);
    dma_default_para_init(&dma_init_struct);
    dma_init_struct.buffer_size = USART1_TX_BUFFER_SIZE;
    dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
    dma_init_struct.memory_base_addr = (uint32_t)usart1_tx_buffer;
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
    dma_init_struct.memory_inc_enable = TRUE;
    dma_init_struct.peripheral_base_addr = (uint32_t)&USART1->dt;
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
    dma_init_struct.peripheral_inc_enable = FALSE;
    dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
    dma_init_struct.loop_mode_enable = FALSE;
    dma_init(DMA1_CHANNEL2, &dma_init_struct);

    /* enable transfer full data interrupt */
    dma_interrupt_enable(DMA1_CHANNEL2, DMA_FDT_INT, TRUE);

    /* dma1 channel2 interrupt nvic init */
    nvic_irq_enable(DMA1_Channel3_2_IRQn, 0, 0);

    /* dma1 channel3 for usart1 rx configuration */
    dma_reset(DMA1_CHANNEL3);
    dma_default_para_init(&dma_init_struct);
    dma_init_struct.buffer_size = USART2_TX_BUFFER_SIZE;
    dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_base_addr = (uint32_t)usart1_rx_buffer;
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
    dma_init_struct.memory_inc_enable = TRUE;
    dma_init_struct.peripheral_base_addr = (uint32_t)&USART1->dt;
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
    dma_init_struct.peripheral_inc_enable = FALSE;
    dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
    dma_init_struct.loop_mode_enable = FALSE;
    dma_init(DMA1_CHANNEL3, &dma_init_struct);

    /* enable transfer full data interrupt */
    dma_interrupt_enable(DMA1_CHANNEL3, DMA_FDT_INT, TRUE);

    /* dma1 channel3 interrupt nvic init */
    nvic_irq_enable(DMA1_Channel3_2_IRQn, 0, 0);

//  dma_channel_enable(DMA1_CHANNEL4, TRUE); /* usart2 tx begin dma transmitting */
    dma_channel_enable(DMA1_CHANNEL2, TRUE); /* usart1 tx begin dma transmitting */
}






低语之树 发表于 2025-11-18 10:00 | 显示全部楼层
中断开了吗,DMA通道配置了没??
 楼主| transtec 发表于 2025-11-18 10:10 | 显示全部楼层
低语之树 发表于 2025-11-18 10:00
中断开了吗,DMA通道配置了没??

中断开了的
dma_channel_enable(DMA1_CHANNEL2, TRUE);

    usart_transmitter_enable(USART1, TRUE);
    usart_receiver_enable(USART1, TRUE);
    usart_dma_transmitter_enable(USART1, TRUE);
    usart_dma_receiver_enable(USART1, TRUE);
    usart_enable(USART1, TRUE);

DMA也是配置了的
void dma_configuration(void)
dffzh 发表于 2025-11-18 11:22 | 显示全部楼层
本帖最后由 dffzh 于 2025-11-18 11:23 编辑

监控过串口发送数据?实际也没有数据发送出去吧?
你是如何确定DMA已经发送完成了?
 楼主| transtec 发表于 2025-11-18 13:52 | 显示全部楼层
本帖最后由 transtec 于 2025-11-18 13:54 编辑
dffzh 发表于 2025-11-18 11:22
监控过串口发送数据?实际也没有数据发送出去吧?
你是如何确定DMA已经发送完成了?
...

如果注释掉这句  if(usart1_tx_dma_status==1),串口助手能收到数据
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

20

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部