求救!CH32V307VCT6如何实现TIM+ADC+DMA实现固定频率采样?

官方EVT只有TIM+ADC和ADC+DMA,我试了几种合并,但是最终还是没实现,DMA传输完成中断进不去

有什么需要注意的点吗


以下为全部代码



#include "debug.h"


/* Global Variable */

s16 Calibrattion_Val = 0;

u16 ADC_ConvertedValue[10];

void DMA_Tx_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_Disable;

    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 = 2;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

}


/*********************************************************************

 * @fn      ADC_Function_Init

 *

 * @brief   Initializes ADC collection.

 *

 * @return  none

 */

void ADC_Function_Init(void)

{

    ADC_InitTypeDef  ADC_InitStructure = {0};

    GPIO_InitTypeDef GPIO_InitStructure = {0};



    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    RCC_ADCCLKConfig(RCC_PCLK2_Div8);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

    GPIO_Init(GPIOA, &GPIO_InitStructure);


    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_CC3;

    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

    ADC_InitStructure.ADC_NbrOfChannel = 1;

    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_ExternalTrigInjectedConvCmd(ADC1, ENABLE);

   ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_41Cycles5);

 //  ADC_InjectedSequencerLengthConfig(ADC1, 1);

 //  ADC_InjectedChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_41Cycles5);



//    NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;

//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

//    NVIC_Init(&NVIC_InitStructure);


//    ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);

    DMA_Tx_Init(DMA1_Channel1, (u32)&ADC1->RDATAR, (u32)ADC_ConvertedValue, 1);

      DMA_Cmd(DMA1_Channel1, ENABLE);

    ADC_DMACmd(ADC1, ENABLE);

    ADC_Cmd(ADC1, ENABLE);


    ADC_BufferCmd(ADC1, DISABLE); //disable buffer

    ADC_ResetCalibration(ADC1);

    while(ADC_GetResetCalibrationStatus(ADC1));

    ADC_StartCalibration(ADC1);

    while(ADC_GetCalibrationStatus(ADC1));

    Calibrattion_Val = Get_CalibrationValue(ADC1);


}


/*********************************************************************

 * @fn      TIM1_PWM_In

 *

 * @brief   Initializes PWM.

 *

 * @return  none

 */


void TIM1_PWM_In(u16 arr, u16 psc, u16 ccp)

{

    GPIO_InitTypeDef        GPIO_InitStructure = {0};

    TIM_OCInitTypeDef       TIM_OCInitStructure = {0};

    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_TIM1, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);


    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_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);


    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure.TIM_Pulse = ccp;

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;

    TIM_OC3Init(TIM2, &TIM_OCInitStructure);


    TIM_CtrlPWMOutputs(TIM2, ENABLE);

    TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);

    TIM_ARRPreloadConfig(TIM2, ENABLE);

    TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

    TIM_Cmd(TIM2, ENABLE);

}

/*********************************************************************

 * @fn      Get_ConversionVal1

 *

 * @brief   Get Conversion Value.

 *

 * @param   val - Sampling value

 *

 * @return  val+Calibrattion_Val - Conversion Value.

 */

u16 Get_ConversionVal(s16 val)

{

    if((val + Calibrattion_Val) < 0||val==0)

        return 0;

    if((Calibrattion_Val + val) > 4095 || val==4095)

        return 4095;

    return (val + Calibrattion_Val);

}


/*********************************************************************

 * @fn      main

 *

 * @brief   Main program.

 *

 * @return  none

 */

int main(void)

{

    SystemCoreClockUpdate();

    USART_Printf_Init(115200);

    printf("SystemClk:%d\r\n", SystemCoreClock);


    ADC_Function_Init();



   // ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );

    printf("CalibrattionValue:%d\n", Calibrattion_Val);

    TIM1_PWM_In(1000-1,96-1,500);


    while(1);

}


//void ADC1_2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));


/*********************************************************************

 * @fn      ADC1_2_IRQHandler

 *

 * @brief   ADC1_2 Interrupt Service Function.

 *

 * @return  none

 */

//void ADC1_2_IRQHandler()

//{

//    u16 ADC_val;

//

//    if(ADC_GetITStatus(ADC1, ADC_IT_JEOC))

//    {

//        printf("ADC Extline trigger conversion...\r\n");

//        ADC_val = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);

//

//        printf("JADC %04d\r\n", Get_ConversionVal(ADC_val));

//    }

//

//    ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);

//}


void  DMA1_Channel1_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

void  DMA1_Channel1_IRQHandler(void)

{

    if(DMA_GetITStatus(DMA1_IT_TC1)!=RESET){

        //中断处理代码

        printf("The current value =%d \r\n",ADC_ConvertedValue[0]);

        DMA_ClearITPendingBit(DMA1_IT_TC1);

    }

}



https://www.cnblogs.com/wchmcu/p/17445959.html  看下这个帖子 ,配置少了一点ADC_ExternalTrigConvCmd(ADC1, ENABLE);//   开启外部事件触发ADC启动,ADC的外部触发源与定时器的输出源保持一致,也需要参考ADC外部触发的框图,注意触发频率不要大于ADC所有规则通道采样完的这个时间。DMA的模式可以设为循环模式,这样就不需要重新设置缓冲区与传输长度了。


已解决,谢谢!!!


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