打印

GD32E230使用ADC+TIMER14触发采样,不能工作,请大神帮忙知道一下

[复制链接]
675|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gwlall|  楼主 | 2025-6-3 12:03 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
大家好,请问大家,我在使用GD32E230的定时器触发ADC转换时,基于官方的这个例程把TIMER0改成TIMER14后集成在程序里不能工作(TIMER0在程序里做其他用途了,所以要改成TIMER14)。使能ADC转换完成中断后,未能进中断,用软件触发方式则可以进中断,我感觉是配置有问题未能触发ADC转换。观察TIMER14的寄存器,发现计数器是滚动的。请问大家有没有相关经验,或者哪位大神能帮我解决一下这个问题,可以适当有偿报酬。
/*
***************************************************************************************************
* Includes
***************************************************************************************************
*/
/* global declarations */
#include "common.h"

/* module import interface */
#include "Adc_Inf.h"

/* private module interface */
#include "Adc_Prv.h"


/*
***************************************************************************************************
* Variables
***************************************************************************************************
*/
MEMORY_ALIGNED(4) volatile uint16 Adc_aResultValue[2];

/*
***************************************************************************************************
* used functions
***************************************************************************************************
*/
void Adc_DmaConfig(void);
void Adc_TrigTimerConfig(void);

/**
***************************************************************************************************
* Adc_Init - Initializes the ADC hardware unit and the driver.
*
*
*
* \param           none
* \return          none
* \retval          none
* \seealso         
* \usedresources
***************************************************************************************************
*/
void Adc_Init(void)
{
    /* Enable ADC clock */
    rcu_periph_clock_enable(RCU_ADC);
    /* Config ADC clock */
    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);

    /* Reset ADC */
    adc_deinit();
   
    /* DMA configuration */
    Adc_DmaConfig();

#if (ADC_TRIG_TIMER_ENABLE == STD_ON)
    /* Trigger Timer configuration */
    Adc_TrigTimerConfig();
#endif

    /* ADC scan function enable */
    adc_special_function_config(ADC_SCAN_MODE, ENABLE);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
    /* ADC channel length config */
    adc_channel_length_config(ADC_REGULAR_CHANNEL, 2);

    /* ADC regular channel config */
    adc_regular_channel_config(0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);
    adc_regular_channel_config(1, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
   
    /* ADC trigger config */
#if (ADC_TRIG_TIMER_ENABLE == STD_OFF)
    adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
#else
    adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_T14_CH0);
#endif
    adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);

    /* Enable ADC interface */
    adc_enable();
    Cpu_WaitTime(CPU_MS_TO_TICKS(1));
    /* ADC calibration and reset calibration */
    adc_calibration_enable();

#if (ADC_TRIG_TIMER_ENABLE == STD_OFF)
    /* ADC software trigger enable */
    adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
#endif

    /* ADC DMA function enable */
    adc_dma_mode_enable();

#if (ADC_TRIG_TIMER_ENABLE == STD_ON)
    /* Enable Trigger Timer */
    timer_enable(ADC_TRIG_TIMER);
#endif
   
    /* ADC interrupt config */
    nvic_irq_enable(ADC_CMP_IRQn, 0U);
    adc_interrupt_enable(ADC_INT_EOC);
}


/**
***************************************************************************************************
* Adc_DmaConfig - DMA configuration function.
*
*
*
* \param           none
* \return          none
* \retval          none
* \seealso         
* \usedresources
***************************************************************************************************
*/
void Adc_DmaConfig(void)
{
    dma_parameter_struct dma_init_struct;

    /* Enable DMA clock */
    rcu_periph_clock_enable(RCU_DMA);
   
    /* Initialize DMA channel */
    dma_deinit(DMA_CH0);
    dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr  = (uint32)Adc_aResultValue;
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.number       = 2;
    dma_init_struct.periph_addr  = (uint32)&(ADC_RDATA);
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA_CH0, &dma_init_struct);
   
    /* configure DMA mode */
    dma_circulation_enable(DMA_CH0);
    dma_memory_to_memory_disable(DMA_CH0);
   
    /* enable DMA channel0 */
    dma_channel_enable(DMA_CH0);
}

/**
***************************************************************************************************
* Adc_TrigTimerConfig - Initializes the ADC trigger timer.
*
*
*
* \param           none
* \return          none
* \retval          none
* \seealso         
* \usedresources
***************************************************************************************************
*/
void Adc_TrigTimerConfig(void)
{
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    /* Enable timer clock */
    rcu_periph_clock_enable(RCU_TIMER14);
   
    /* Deinit a timer */
    timer_deinit(TIMER14);
    /* Initialize TIMER init parameter struct */
    timer_struct_para_init(&timer_initpara);
    /* Timer configuration */
    timer_initpara.prescaler         = 5;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 399;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER14, &timer_initpara);

    /* CHx configuration in PWM mode1 */
    timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_LOW;
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    timer_channel_output_config(TIMER14, TIMER_CH_0, &timer_ocintpara);

    timer_channel_output_pulse_value_config(TIMER14, TIMER_CH_0, 100);
    timer_channel_output_mode_config(TIMER14, TIMER_CH_0, TIMER_OC_MODE_PWM1);
    timer_channel_output_shadow_config(TIMER14, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
   
    /* Auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER14);
    timer_primary_output_config(TIMER14, ENABLE);
}


官方例程.rar

2.97 KB

我的程序.rar

1.57 KB

使用特权

评论回复
沙发
tax2r6c| | 2025-6-4 12:36 | 只看该作者
确保ADC的触发源已正确配置为TIMER14的输出信号。在GD32E230中,ADC的触发源通过ADC_CTL0寄存器的TRGSEL位选择。

使用特权

评论回复
板凳
b5z1giu| | 2025-6-4 13:42 | 只看该作者
TIMER14需配置为PWM模式或定时触发模式,输出与ADC触发需求匹配的信号。确保TIMER14的触发信号是上升沿或高电平(具体取决于ADC触发极性配置)。

使用特权

评论回复
地板
lamanius| | 2025-6-4 14:52 | 只看该作者
配置TIMER14为PWM模式,设置合适的占空比(如50%),确保触发信号有效。

使用特权

评论回复
5
kaif2n9j| | 2025-6-4 16:01 | 只看该作者
若ADC触发极性为上升沿触发,需确保TIMER14输出信号包含上升沿。

使用特权

评论回复
6
d1ng2x| | 2025-6-4 17:10 | 只看该作者
ADC转换完成中断(EOC)需在ADC_CTL0寄存器中使能,并在NVIC中配置中断优先级

使用特权

评论回复
7
cen9ce| | 2025-6-4 18:16 | 只看该作者
验证中断服务程序(ISR),确保ADC中断服务程序(ISR)已正确定义,并在其中清除中断标志位。

使用特权

评论回复
8
suw12q| | 2025-6-4 19:33 | 只看该作者
触发信号与ADC启动时序,ADC需在TIMER14触发信号到来时处于就绪状态。若ADC未准备好,可能丢失触发信号。

使用特权

评论回复
9
w2nme1ai7| | 2025-6-5 09:21 | 只看该作者
在启动TIMER14之前,先初始化并使能ADC,并添加适当的延时(如delay_ms(20))。

使用特权

评论回复
10
y1n9an| | 2025-6-5 11:09 | 只看该作者
确保ADC的校准已完成(调用ADC_CAL函数)。

使用特权

评论回复
11
dffzh| | 2025-6-5 11:26 | 只看该作者
本帖最后由 dffzh 于 2025-6-5 11:30 编辑

基于官方的这个例程把TIMER0改成TIMER14后集成在程序里不能工作”:
我看官网上的例程关于定时器触发ADC采样的,好像只有使用定时器2+ADC配置为注入模式的吧?



不过你这个adc_external_trigger_source_config函数的配置看上去也没问题。
你可以用这个Timer_trigger_injected_channel文件夹demo,认真对比一下初始化配置(按我经验,基本上是代码配置问题),并将触发模式改为
adc_external_trigger_source_config(ADC_INSERTED_CHANNEL,ADC_EXTTRIG_INSERTED_T14_TRGO);
试试。如果还不行,再回复我,我帮你看下。

使用特权

评论回复
12
q1d0mnx| | 2025-6-5 13:02 | 只看该作者
触发信号频率与ADC采样率匹配,TIMER14的触发频率需低于ADC的最大采样率(GD32E230的ADC最大采样率通常为1MHz)。若频率过高,可能导致ADC无法响应。

使用特权

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

本版积分规则

2

主题

5

帖子

0

粉丝