AnsweredAssumed Answered

STM32F334 ADC never converts

Question asked by yellin.david on Jan 17, 2015
I can't figure out why I never get any readings on the ADC or even manage to trigger the ADC interrupt. Maybe someone could look at the following code?

The idea is to convert 3 channels on ADC1 and 3 channels on ADC2, with triggering from HRTIM. Unfortunately it never triggers and nothing converts...

/**
 * @brief  ADC configuration
 * @param  None
 * @retval None
 */
static void ADC_Config(void) {
 
    /* Configure the ADC clock */
    RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div1);
    /* Enable ADC1 clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);
 
    /* ADC GPIO configuration */
    ADC_GPIO_Configuration();
 
    /* ADC DMA Channel configuration */
    ADC_DMA_Configuration();
    /* ADC calibration */
    ADC_Calibrate();
 
    /* ADC mode configuration */
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_CommonInitStructure.ADC_Clock = ADC_Clock_SynClkModeDiv4;
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_OneShot;
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = 0;
 
    ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
    ADC_CommonInit(ADC2, &ADC_CommonInitStructure);
 
    /* */
 
    ADC_StructInit(&ADC_InitStructure);
 
    ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_9; /* HRTIM_ADCTRG2 */
    ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_RisingEdge;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;
    ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;
    ADC_Init(ADC1, &ADC_InitStructure);
 
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_10; /* HRTIM_ADCTRG4 */
    ADC_Init(ADC2, &ADC_InitStructure);
 
    ADC_InjectedStructInit(&ADC_InjectedInitStruct);
 
    ADC_InjectedInitStruct.ADC_ExternalTrigInjecConvEvent = ADC_ExternalTrigInjecConvEvent_9;
    ADC_InjectedInitStruct.ADC_ExternalTrigInjecEventEdge =
    ADC_ExternalTrigInjecEventEdge_RisingEdge;
    ADC_InjectedInitStruct.ADC_InjecSequence1 = ADC_InjectedChannel_3; /* corresponds to PA2 CS */
    ADC_InjectedInitStruct.ADC_InjecSequence2 = ADC_InjectedChannel_13; /* corresponds to PB13 VOUT */
    ADC_InjectedInitStruct.ADC_InjecSequence3 = ADC_InjectedChannel_1; /* corresponds to PA0 TEMP */
    ADC_InjectedInitStruct.ADC_NbrOfInjecChannel = 3;
 
    ADC_InjectedInit(ADC1, &ADC_InjectedInitStruct);
 
    ADC_InjectedInitStruct.ADC_ExternalTrigInjecConvEvent = ADC_ExternalTrigInjecConvEvent_10;
    ADC_InjectedInitStruct.ADC_ExternalTrigInjecEventEdge =
    ADC_ExternalTrigInjecEventEdge_RisingEdge;
    ADC_InjectedInitStruct.ADC_InjecSequence1 = ADC_InjectedChannel_12; /* corresponds to PB2 CS */
    ADC_InjectedInitStruct.ADC_InjecSequence2 = ADC_InjectedChannel_13; /* corresponds to PB12 VOUT */
    ADC_InjectedInitStruct.ADC_InjecSequence3 = ADC_InjectedChannel_14; /* corresponds to PB14 VIN */
    ADC_InjectedInitStruct.ADC_NbrOfInjecChannel = 3;
 
    ADC_InjectedInit(ADC2, &ADC_InjectedInitStruct);
 
    /* ADC2 channel1 configuration */
    /* Example VIN Tconv = Tsamp (7.5) + 12.5 ADC clock cycles = 20 ADC clock samples = 278ns @72MHz */
    ADC_InjectedChannelSampleTimeConfig(ADC1, ADC_Channel_3,
            ADC_SampleTime_7Cycles5); /* CS */
    ADC_InjectedChannelSampleTimeConfig(ADC1, ADC_Channel_13,
            ADC_SampleTime_7Cycles5); /* VOUT */
    ADC_InjectedChannelSampleTimeConfig(ADC1, ADC_Channel_1,
            ADC_SampleTime_7Cycles5); /* TEMP */
    ADC_InjectedChannelSampleTimeConfig(ADC2, ADC_Channel_12,
            ADC_SampleTime_7Cycles5); /* CS */
    ADC_InjectedChannelSampleTimeConfig(ADC2, ADC_Channel_13,
            ADC_SampleTime_7Cycles5); /* VOUT */
    ADC_InjectedChannelSampleTimeConfig(ADC2, ADC_Channel_14,
            ADC_SampleTime_7Cycles5); /* VIN */
 
    /* Configure and enable ADC12 interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
 
    /* Enable JEOC interrupt */
    ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);
    ADC_ITConfig(ADC2, ADC_IT_JEOC, ENABLE);
 
    /*HRTIM trigger configuration for ADC1 */
    pADCTriggerCfg.UpdateSource = HRTIM_ADCTRIGGERUPDATE_TIMER_A;
    pADCTriggerCfg.Trigger = HRTIM_ADCTRIGGEREVENT24_TIMERA_CMP3;
    HRTIM_ADCTriggerConfig(HRTIM1, HRTIM_ADCTRIGGER_2, &pADCTriggerCfg);
 
    /*HRTIM trigger configuration for ADC2 */
    pADCTriggerCfg.UpdateSource = HRTIM_ADCTRIGGERUPDATE_TIMER_B;
    pADCTriggerCfg.Trigger = HRTIM_ADCTRIGGEREVENT24_TIMERB_CMP3;
    HRTIM_ADCTriggerConfig(HRTIM1, HRTIM_ADCTRIGGER_4, &pADCTriggerCfg);
 
    /* Configures the ADC DMA */
    ADC_DMAConfig(ADC1, ADC_DMAMode_Circular);
    /* Enable the ADC DMA */
    ADC_DMACmd(ADC1, ENABLE);
 
    /* Configures the ADC DMA */
    ADC_DMAConfig(ADC2, ADC_DMAMode_Circular);
    /* Enable the ADC DMA */
    ADC_DMACmd(ADC2, ENABLE);
 
    /* Enable ADC1 and ADC2 */
    ADC_Cmd(ADC1, ENABLE);
    ADC_Cmd(ADC2, ENABLE);
 
    /* wait for ADC1 ADRDY */
    while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY))
        ;
 
    /* wait for ADC2 ADRDY */
    while (!ADC_GetFlagStatus(ADC2, ADC_FLAG_RDY))
        ;
 
    /* Enable the DMA channel */
    DMA_Cmd(DMA1_Channel1, ENABLE);
    DMA_Cmd(DMA1_Channel2, ENABLE);
 
    /* Start ADC1 Conversion */
    ADC_StartInjectedConversion(ADC1);
 
    /* Start ADC2 Conversion */
    ADC_StartInjectedConversion(ADC2);
 
 
    /* Start ADC1 Conversion */
    ADC_StartConversion(ADC1);
 
    /* Start ADC2 Conversion */
    ADC_StartConversion(ADC2);
}
 
/**
 * @brief  Configures the ADCs GPIO pins.
 * @param  None
 * @retval None
 */
 
void ADC_GPIO_Configuration(void) {
 
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOC, ENABLE);
    /* ADC Channel configuration */
    /* Configure ADC Channel1 as analog input / PA0/TEMP */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    ADC_StructInit(&ADC_InitStructure);
 
    /* Configure ADC Channel3 as analog input / PA2/P2_CS */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
    ADC_StructInit(&ADC_InitStructure);
 
    /* Configure ADC Channel12 as analog input / PB13/P2_VOUT */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
 
    ADC_StructInit(&ADC_InitStructure);
 
    /* ADC Channel configuration */
    /* Configure ADC Channel12 as analog input / PB2/P1_CS */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
 
    ADC_StructInit(&ADC_InitStructure);
 
    /* Configure ADC Channel13 as analog input / PB12/P1_VOUT */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
 
    ADC_StructInit(&ADC_InitStructure);
 
    /* Configure ADC Channel14 as analog input / PB14/VIN */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}
 
/**
 * @brief  ADC calibration
 * @param  None
 * @retval None
 */
void ADC_Calibrate(void) {
 
    ADC_StructInit(&ADC_InitStructure);
 
    /* ADC Calibration procedure */
      ADC_VoltageRegulatorCmd(ADC1, ENABLE);
      ADC_VoltageRegulatorCmd(ADC2, ENABLE);
 
      /* Insert delay equal to 10 µs */
      Delay(10);
 
      ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
      ADC_StartCalibration(ADC1);
 
      ADC_SelectCalibrationMode(ADC2, ADC_CalibrationMode_Single);
      ADC_StartCalibration(ADC2);
 
      while(ADC_GetCalibrationStatus(ADC1) != RESET );
      calibration_value_1 = ADC_GetCalibrationValue(ADC1);
 
      while(ADC_GetCalibrationStatus(ADC2) != RESET );
      calibration_value_2 = ADC_GetCalibrationValue(ADC2);
}
 
/**
 * @brief  Configures the ADCs DMA channel.
 * @param  None
 * @retval None
 */
void ADC_DMA_Configuration(void) {
    DMA_InitTypeDef DMA_InitStructure;
    /* Enable DMA1 clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
 
    /* DMA configuration */
    /* DMA1 Channel1 Init Test */
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ADC1_JDR1_ADDRESS;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &ADC1_ConvertedValue;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 3;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
 
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
 
    /* DMA configuration */
    /* DMA1 Channel2 Init Test */
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ADC2_JDR1_ADDRESS;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &ADC2_ConvertedValue;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 3;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
 
    DMA_Init(DMA1_Channel2, &DMA_InitStructure);
}

Outcomes