打印
[AT32F421]

AT32F437ZGT7的ADC+EDMA+Time模式采集的ADC数据,运行一段时间后

[复制链接]
1642|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhitao2072|  楼主 | 2023-8-18 14:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
AD, ADC, DM, DMA, TI
void bsp_adc_init(void)
{
    adc_common_init();

    adc1_init();
    adc1_edma_init();

    adc3_init();
    adc3_edma_init();

    tmr2_init(BSP_ADC_SAMPLE_TIMES_PER_1MS * 1000); // timer init
}




使用特权

评论回复
沙发
zhitao2072|  楼主 | 2023-8-18 14:26 | 只看该作者
static void adc_common_init(void)
{
    adc_common_config_type adc_common_struct;

    adc_common_default_para_init(&adc_common_struct);

    /* config combine mode */
    adc_common_struct.combine_mode = ADC_INDEPENDENT_MODE;

    /* config division,adcclk is division by hclk */
    adc_common_struct.div = ADC_HCLK_DIV_16;

    /* config common dma mode,it's not useful in independent mode */
    adc_common_struct.common_dma_mode = ADC_COMMON_DMAMODE_DISABLE;

    /* config common dma request repeat */
    adc_common_struct.common_dma_request_repeat_state = FALSE;

    /* config adjacent adc sampling interval,it's useful for ordinary shifting mode */
    adc_common_struct.sampling_interval = ADC_SAMPLING_INTERVAL_20CYCLES;

    /* config inner temperature sensor and vintrv */
    adc_common_struct.tempervintrv_state = FALSE;

    /* config voltage battery */
    adc_common_struct.vbat_state = FALSE;
    adc_common_config(&adc_common_struct);
}

使用特权

评论回复
板凳
zhitao2072|  楼主 | 2023-8-18 14:26 | 只看该作者
static void adc1_init(void)
{
    adc_base_config_type adc_base_struct;
    crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);

    adc_base_default_para_init(&adc_base_struct);

    adc_base_struct.sequence_mode = TRUE;
    adc_base_struct.repeat_mode = FALSE;
    adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
    adc_base_struct.ordinary_channel_length = 7;
    adc_base_config(ADC1, &adc_base_struct);
    adc_resolution_set(ADC1, ADC_RESOLUTION_12B);

    for (uint8_t i = 0; i < BSP_ADC1_USED_NUM; i++)
    {
        bsp_gpio_pin_init(bsp_adc_pin[adc1_used_ch[i]].port,
                          bsp_adc_pin[adc1_used_ch[i]].pin,
                          BSP_GPIO_MODE_AN,
                          BSP_GPIO_DRV_MODERATE,
                          BSP_GPIO_PUPD_NULL,
                          BSP_GPIO_OTYPE_OD);
    }

    /* config ordinary channel */
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_13, 1, ADC_SAMPLETIME_640_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_0, 2, ADC_SAMPLETIME_640_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_8, 3, ADC_SAMPLETIME_640_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_9, 4, ADC_SAMPLETIME_640_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_10, 5, ADC_SAMPLETIME_640_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_12, 6, ADC_SAMPLETIME_640_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_3, 7, ADC_SAMPLETIME_640_5);

    /* config ordinary trigger source and trigger edge */
    adc_ordinary_conversion_trigger_set(ADC1, ADC_ORDINARY_TRIG_TMR2CH2, ADC_ORDINARY_TRIG_EDGE_RISING);

    /* config dma mode,it's not useful when common dma mode is use */
    adc_dma_mode_enable(ADC1, TRUE);

    /* config dma request repeat,it's not useful when common dma mode is use */
    adc_dma_request_repeat_enable(ADC1, TRUE);

    /* adc enable */
    adc_enable(ADC1, TRUE);
    while (adc_flag_get(ADC1, ADC_RDY_FLAG) == RESET)
        ;

    /* adc calibration */
    adc_calibration_init(ADC1);
    while (adc_calibration_init_status_get(ADC1))
        ;
    adc_calibration_start(ADC1);
    while (adc_calibration_status_get(ADC1))
        ;
}

使用特权

评论回复
地板
zhitao2072|  楼主 | 2023-8-18 14:26 | 只看该作者
static void adc1_edma_init(void)
{
    edma_init_type edma_init_struct;
    crm_periph_clock_enable(CRM_EDMA_PERIPH_CLOCK, TRUE);

#if (ADC_DMA_IT_EN > 0)
    nvic_irq_enable(EDMA_Stream5_IRQn, 0, 0);
#endif

    edma_reset(EDMA_STREAM5);
    edma_default_para_init(&edma_init_struct);
    edma_init_struct.buffer_size = ADC1_RAW_DATA_BUF_SIZE;
    edma_init_struct.direction = EDMA_DIR_PERIPHERAL_TO_MEMORY;
    edma_init_struct.memory0_base_addr = (u32)(bsp_adc1_raw);
    edma_init_struct.memory_burst_mode = EDMA_MEMORY_SINGLE;
    edma_init_struct.memory_data_width = EDMA_MEMORY_DATA_WIDTH_HALFWORD;
    edma_init_struct.memory_inc_enable = TRUE;
    edma_init_struct.peripheral_base_addr = (uint32_t) & (ADC1->odt);
    edma_init_struct.peripheral_burst_mode = EDMA_PERIPHERAL_SINGLE;
    edma_init_struct.peripheral_data_width = EDMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
    edma_init_struct.peripheral_inc_enable = FALSE;
    edma_init_struct.priority = EDMA_PRIORITY_HIGH;
    edma_init_struct.loop_mode_enable = TRUE;
    edma_init_struct.fifo_threshold = EDMA_FIFO_THRESHOLD_1QUARTER;
    edma_init_struct.fifo_mode_enable = FALSE;
    edma_init(EDMA_STREAM5, &edma_init_struct);

    /* edmamux init and enable */
    edmamux_enable(TRUE);
    edmamux_init(EDMAMUX_CHANNEL5, EDMAMUX_DMAREQ_ID_ADC1);

    /* enable edma full data transfer intterrupt */
#if (ADC_DMA_IT_EN > 0)
    edma_interrupt_enable(EDMA_STREAM5, EDMA_FDT_INT, TRUE);
#else
    edma_interrupt_enable(EDMA_STREAM5, EDMA_FDT_INT, FALSE);
#endif

    edma_stream_enable(EDMA_STREAM5, TRUE);
}

使用特权

评论回复
5
zhitao2072|  楼主 | 2023-8-18 14:27 | 只看该作者
static void tmr2_init(uint32_t freq)
{
    tmr_output_config_type tmr_oc_init_structure;
    crm_clocks_freq_type crm_clocks_freq_struct = {0};

    /* get system clock */
    crm_clocks_freq_get(&crm_clocks_freq_struct);

    crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);

#if (ADC_TIM_IT_EN > 0)
    nvic_irq_enable(TMR2_GLOBAL_IRQn, 1, 0);
#endif

    tmr_base_init(TMR2, 1, (crm_clocks_freq_struct.sclk_freq / 2 / freq) - 1);
    tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR2, TMR_CLOCK_DIV2);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
    tmr_oc_init_structure.oc_output_state = TRUE;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_2, 1);

#if (ADC_TIM_IT_EN > 0)
    tmr_interrupt_enable(TMR2, TMR_OVF_INT, TRUE);
#else
    tmr_interrupt_enable(TMR2, TMR_OVF_INT, FALSE);
#endif

    tmr_period_buffer_enable(TMR2, FALSE);

    tmr_channel_enable(TMR2, TMR_SELECT_CHANNEL_2, TRUE);
    tmr_counter_enable(TMR2, TRUE);
    tmr_output_enable(TMR2, TRUE);
}

使用特权

评论回复
6
zhitao2072|  楼主 | 2023-8-18 14:39 | 只看该作者
AT32F437ZGT7的ADC+EDMA+Time模式采集的ADC数据,运行一段时间后采集数据不会更新了,ADC死掉一样。

使用特权

评论回复
7
zhitao2072|  楼主 | 2023-8-18 14:40 | 只看该作者
死掉后的log信息timercount = 33120355; bsp_adc1_raw:
1693 1695 1695 1693 1706 1697 1692 1691 1693 1699
timercount = 33140355; bsp_adc1_raw:
1693 1695 1695 1693 1706 1697 1692 1691 1693 1699
timercount = 33160355; bsp_adc1_raw:
1693 1695 1695 1693 1706 1697 1692 1691 1693 1699
timercount = 33180355; bsp_adc1_raw:
1693 1695 1695 1693 1706 1697 1692 1691 1693 1699
timercount = 33200355; bsp_adc1_raw:
1693 1695 1695 1693 1706 1697 1692 1691 1693 1699
timercount = 33220355; bsp_adc1_raw:
1693 1695 1695 1693 1706 1697 1692 1691 1693 1699
timercount = 33240355; bsp_adc1_raw:
1693 1695 1695 1693 1706 1697 1692 1691 1693 1699
timercount = 33260355; bsp_adc1_raw:
1693 1695 1695 1693 1706 1697 1692 1691 1693 1699

使用特权

评论回复
8
tanleitanlei| | 2023-8-18 15:20 | 只看该作者
zhitao2072 发表于 2023-8-18 14:39
AT32F437ZGT7的ADC+EDMA+Time模式采集的ADC数据,运行一段时间后采集数据不会更新了,ADC死掉一样。 ...

将你的代码移过来跑了一下,没有出现死掉的现象。如果可以请提供简化后的可复现问题的工程代码

使用特权

评论回复
9
zhitao2072|  楼主 | 2023-8-18 15:25 | 只看该作者
tanleitanlei 发表于 2023-8-18 15:20
将你的代码移过来跑了一下,没有出现死掉的现象。如果可以请提供简化后的可复现问题的工程代码 ...

我这边是电动汽车充电行业,充电一段时间后出现,只是简单的在办公司跑代码我这边也不会出现。

使用特权

评论回复
10
tanleitanlei| | 2023-8-18 15:47 | 只看该作者
zhitao2072 发表于 2023-8-18 15:25
我这边是电动汽车充电行业,充电一段时间后出现,只是简单的在办公司跑代码我这边也不会出现。 ...

那这样的话我这边暂时没办法帮你了,看你能否联系到AT32技术支持寻求帮助了

使用特权

评论回复
11
tpgf| | 2023-9-7 11:57 | 只看该作者
edma和我们常说的普通的dma的区别是什么

使用特权

评论回复
12
八层楼| | 2023-9-7 13:19 | 只看该作者
通过灵活控制EDMA不仅能够提高图像数据的传输效率

使用特权

评论回复
13
guanjiaer| | 2023-9-7 14:06 | 只看该作者
事件寄存器完成对EDMA事件的捕获、控制。若有多个事件同时发生,由事件编码器对它们进行处理(将同时发生的事件进行排队)。

使用特权

评论回复
14
heimaojingzhang| | 2023-9-7 21:41 | 只看该作者
EDMA控制器与DMA控制器在结构上有所区别

使用特权

评论回复
15
观海| | 2023-9-7 22:09 | 只看该作者
EDMA控制器可以独立于CPU处理L2 Cache/SRAM和C64x外设之间的数据传输

使用特权

评论回复
16
晓伍| | 2023-9-7 22:39 | 只看该作者
EDMA是数字信号处理器(DSP)中用于快速数据交换的重要技术,具有独立于CPU的后台批量数据传输的能力,能够满足实时图像处理中高速数据传输的要求

使用特权

评论回复
17
zhitao2072|  楼主 | 2023-10-28 11:11 | 只看该作者
#if (ADC_DMA_IT_EN > 0)
//uint32_t adc1_dma_cntr;
void EDMA_Stream5_IRQHandler(void)
{
    BSP_ENTR_ISR();

    if (edma_flag_get(EDMA_FDT5_FLAG))
    {
        //adc1_dma_cntr++;
        adc.adc1cnt++;
        edma_flag_clear(EDMA_FDT5_FLAG);
    }
    else if(edma_flag_get(EDMA_FERR5_FLAG))
    {
        edma_flag_clear(EDMA_FERR5_FLAG);
    }
    else if(edma_flag_get(EDMA_DMERR5_FLAG))
    {
        edma_flag_clear(EDMA_DMERR5_FLAG);
    }
    else if(edma_flag_get(EDMA_DTERR5_FLAG))
    {
        edma_flag_clear(EDMA_DTERR5_FLAG);
    }

    BSP_EXIT_ISR();
}
#endif

使用特权

评论回复
18
zhitao2072|  楼主 | 2023-10-28 11:11 | 只看该作者
#if (ADC_DMA_IT_EN > 0)
//uint32_t adc3_dma_cntr;
void EDMA_Stream6_IRQHandler(void)
{
    BSP_ENTR_ISR();

    if (edma_flag_get(EDMA_FDT6_FLAG))
    {
        edma_flag_clear(EDMA_FDT6_FLAG);
        //adc3_dma_cntr++;
        adc.adc3cnt++;
    }
    else if(edma_flag_get(EDMA_FERR6_FLAG))
    {
        edma_flag_clear(EDMA_FERR6_FLAG);
    }
    else if(edma_flag_get(EDMA_DMERR6_FLAG))
    {
        edma_flag_clear(EDMA_DMERR6_FLAG);
    }
    else if(edma_flag_get(EDMA_DTERR6_FLAG))
    {
        edma_flag_clear(EDMA_DTERR6_FLAG);
    }
    BSP_EXIT_ISR();
}
#endif

使用特权

评论回复
19
zhitao2072|  楼主 | 2023-10-28 11:12 | 只看该作者
#if (ADC_TIM_IT_EN > 0)
// uint32_t tmr2_cntr;
void TMR2_GLOBAL_IRQHandler(void)
{
    BSP_ENTR_ISR();

    if (tmr_flag_get(TMR2, TMR_OVF_FLAG) != RESET)
    {
        tmr_flag_clear(TMR2, TMR_OVF_FLAG);
        // tmr2_cntr++;
        adc.timercnt++;
    }

    BSP_EXIT_ISR();
}
#endif

使用特权

评论回复
20
zhitao2072|  楼主 | 2023-10-28 11:13 | 只看该作者
adc.taskcount++;
    if(adc.taskcount % 2000 == 10)
    {
        if(adc.adc1cnt_last != adc.adc1cnt)
        {
            adc.adc1cnt_last = adc.adc1cnt;
        }  
        else
        {
            app_adc_init();
        }

        if(adc.adc3cnt_last != adc.adc3cnt)
        {
            adc.adc3cnt_last = adc.adc3cnt;
        }  
        else
        {
            app_adc_init();
        }

        rt_kprintf("cnt = %d %d %d; bsp_adc1_raw:\r\n",
                    adc.timercnt, adc.adc1cnt, adc.adc3cnt);
        for(i=0;i<BSP_ADC_RAW_DATA_NUM;i++)
            rt_kprintf("%d ",bsp_adc1_raw[i][4]);
        rt_kprintf("\n");
    }

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

440

帖子

2

粉丝