CH32X033----TIM2 TRGO事件无法触发ADC采样,请帮我看看问题出在哪

问题如标题,以下是我程序

#include "debug.h"
#include "string.h"

#define FFT_len 128

uint8_t ADC_measure_flag = 0;//ADC测量完成 标志位
int16_t ADC_buff[FFT_len];

void GPIO_Toggle_INIT()
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void TIM2_Init(u16 arr, u16 psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    TIM_TimeBaseInitStructure.TIM_Period = arr;
    TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);

    //TIM_ARRPreloadConfig(TIM2, ENABLE);
    TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);
    TIM_Cmd(TIM2,ENABLE);
}
void DMA_ADC_Init(DMA_Channel_TypeDef *DMA_CHx, u32 ppadr, u32 memadr, u16 bufsize)
{
    DMA_InitTypeDef DMA_InitStructure = {0};
    NVIC_InitTypeDef NVIC_InitStructure={0};

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    DMA_DeInit(DMA_CHx);
    DMA_InitStructure.DMA_PeripheralBaseAddr = ppadr;
    DMA_InitStructure.DMA_MemoryBaseAddr = memadr;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = bufsize;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA_CHx, &DMA_InitStructure);

    DMA_ITConfig(DMA1_Channel1,DMA_IT_TC, ENABLE);      //使能传输完成中断
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    DMA_Cmd(DMA1_Channel1 , ENABLE);  //使能DMA
}
void ADC_TRGO_Init()
{
    ADC_InitTypeDef  ADC_InitStructure = {0};
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ADC_CLKConfig(ADC1, ADC_CLK_Div6);
    ADC_DeInit(ADC1);
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_9Cycles);
    ADC_ExternalTrigConvCmd(ADC1, ENABLE);//设置外部触发模式使能
    ADC_Cmd(ADC1, ENABLE);
}
void ADC_DMA_CONF()
{
    memset(ADC_buff,0,sizeof(ADC_buff));
    ADC_TRGO_Init();
    DMA_ADC_Init(DMA1_Channel1, (u32)&ADC1->RDATAR, (u32)ADC_buff, FFT_len);
    ADC_DMACmd(ADC1, ENABLE);
}
int main(void)
{
        u8 i = 0;
        
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    SystemCoreClockUpdate();
    Delay_Init();
    GPIO_Toggle_INIT();

    Delay_Ms(300);
    
    TIM2_Init(100,48-1); //10K
    ADC_DMA_CONF();
    while(1)
    {
        if(ADC_measure_flag)
        {
            ADC_measure_flag = 0;
            //启动ADC采集
            DMA1_Channel1->CNTR = FFT_len;
            DMA1_Channel1->MADDR = (uint32_t)ADC_buff;
            DMA1_Channel1->CFGR |= DMA_CFGR1_EN;

            GPIO_WriteBit(GPIOA, GPIO_Pin_10, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));
        }
    }
}
__attribute__((interrupt("WCH-Interrupt-fast")))
void DMA1_Channel1_IRQHandler()
{ 
   if(DMA_GetITStatus(DMA1_IT_TC1)!=RESET) 
   {
       ADC_measure_flag = 1;
       DMA_ClearITPendingBit(DMA1_IT_TC1);
   }
}


你好。我试了一下,并没有问题.因为中断进入的太快了,看不出来灯闪烁,用仿真打断点就可以观察到了。


 uint8_t ADC_measure_flag = 0;这个ADC测量完成 标志位加上volatile 防止被优化。

判断中加上关闭中断并延时

        if(ADC_measure_flag)

        {

            __disable_irq();

            Delay_Ms(500);

            ADC_measure_flag = 0;

            //启动ADC采集

            DMA1_Channel1->CNTR = FFT_len;

            DMA1_Channel1->MADDR = (uint32_t)ADC_buff;

            DMA1_Channel1->CFGR |= DMA_CFGR1_EN;


            GPIO_WriteBit(GPIOA, GPIO_Pin_10, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));

            __enable_irq();

        }



谢谢,加volatile防止ADC_measure_flag 被优化后没问题了


只有登录才能回复,可以选择微信账号登录