STM32F205 ADC DMA 多通道 定时触发问题

2019-07-20 23:21发布

各位大侠求助:
     使用STM32F205调试ADC问题,因为有多个通道,采用定时器3溢出事件触发ADC采样,多个通道,使用DMA方式进行数据传输,使用ST-link调试,发现能进DMA中断,但是既不是全中断,也不是半中断(配置DMA开了全中断和半中断),求解。谢谢。

    附上源码:

void ADC_GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    /* Enable GPIOA GPIOC clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_2| GPIO_Pin_3;//PA3->PR
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //不带上下拉
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}


static void DMA_NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Configure one bit for preemption priority */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}


static void TIM3_Configuration(void) //ADC采样定时器
{
    TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
    /* Enable TIM3 clock */
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE);
    TIM_DeInit(TIM3);
//    TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);                   //把TIM_TimeBaseStructure中的每一个参数按缺省值填入
    TIM_TimeBaseStructure.TIM_Period = 7500-1;                  //自动装载周期
    TIM_TimeBaseStructure.TIM_Prescaler = 0;                    //时钟预分频
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //不分割时钟30MHz
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);             //定时250us,ADC采样率为4k
    TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);
    TIM_Cmd(TIM3, ENABLE);
}


static void ADC1_Configuration(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    /* Enable DMA2 、ADC1 clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
#if 1
    /* DMA2_Stream0_Channel_0  Configuration ------------------------------*/
    DMA_DeInit(DMA2_Stream0);
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)ADC1_DR_Address;        //DAC1转换完成后的数据存放地址
    DMA_InitStructure.DMA_Memory0BaseAddr = (u32)ADC_ConvertedValue;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_BufferSize = CHANNEL_BUF_TOTAL_SIZE;
    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_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA2_Stream0, &DMA_InitStructure);
    DMA_NVIC_Config();
    DMA_ITConfig(DMA2_Stream0,DMA_IT_TC|DMA_IT_HT,ENABLE);
    DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_HTIF0 | DMA_FLAG_TCIF0);
    /* Enable DMA2 steam0  */
    DMA_Cmd(DMA2_Stream0, ENABLE);
#endif
    /* Common configuration (applicable for the three ADCs) ******/
    /* Single ADC mode */
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    /* ADCCLK = PCLK2/4 */
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;         //对60MHz进行4分频
    /* Available only for multi ADC mode */
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled ;//ADC_DMAAccessMode_2 ADC_DMAAccessMode_Disabled
    /* Delay between 2 sampling phases */
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    ADC_CommonInit(&ADC_CommonInitStructure);
    /* Configure ADC1 to convert continously channel14 ***********/
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode =DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;      // ADC_ExternalTrigConv_T3_CC1
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; //ADC_ExternalTrigConvEdge_Rising   ADC_ExternalTrigConvEdge_None
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = CHANNEL_SIZE;//;
    ADC_Init(ADC1, &ADC_InitStructure);
    //PR
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3,  8, ADC_SampleTime_56Cycles); //8

    //
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 7, ADC_SampleTime_56Cycles);
    //US1
    ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 6, ADC_SampleTime_56Cycles);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1,  5, ADC_SampleTime_56Cycles);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 4, ADC_SampleTime_56Cycles);
    //US2
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2,  3, ADC_SampleTime_56Cycles);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_0,  2, ADC_SampleTime_56Cycles);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_56Cycles);
    /*Enables or disables the ADC DMA request after last transfer(Single-ADC mode)*/
    ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
    /* Enables or disables the specified ADCx DMA request */

    //ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
    ADC_ClearFlag(ADC1,ADC_FLAG_EOC | ADC_FLAG_OVR);
    /* Enable ADC1 */
    ADC_Cmd(ADC1, ENABLE);
    ADC_DMACmd(ADC1, ENABLE);
//      ADC_SoftwareStartConv(ADC1);
}


void ADC1_Init(void)
{
    ADC_GPIO_Configuration();
    TIM3_Configuration();
    ADC1_Configuration();
}



最怪异的是中断函数,在两个if(DMA_GetITStatus(xxx))处打断点能进,DMA_ClearFlag ( DMA2_Stream0,DMA_FLAG_TCIF0);和DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_HTIF0);却不能执行到但却不是这两个中断引发的,求解?
void DMA2_Stream0_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA2_Stream0,DMA_FLAG_TCIF0) != RESET )//全中断
    {
        DMA_ClearFlag ( DMA2_Stream0,DMA_FLAG_TCIF0);
           //执行不到
    }
    else if(DMA_GetITStatus(DMA2_Stream0,DMA_FLAG_HTIF0) != RESET )//半中断  
    {
        DMA_ClearFlag(DMA2_Stream0,DMA_FLAG_HTIF0);
         //执行不到
    }
    else
    {
        //从这执行退出了
        DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_HTIF0 | DMA_FLAG_TCIF0| DMA_FLAG_DMEIF0);
        return;
    }

}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。