cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F102C8 ADC3 Interupt routine missing in STM32F10x_StdPeriph_Driver

kt1023
Associate
Posted on February 28, 2014 at 12:50

Hi,

I have noticed that anything related to ADC3 interrupts is missing in the

STM32F10x_StdPeriph_Driver. Since the RM contains information about it, I added the needed ADC3 interrupt routine and enum value to the library but no interrupt occurs. I'm suspecting that some issue might exist with ADC3 interrupts and I hope someone can help.

I have tried to change the startup_stm32f10x_md_vl.s to contain:

...

    .word    RTCAlarm_IRQHandler

    .word    CEC_IRQHandler

    .word    0

    .word    0

    .word    0

    .word    0

    .word    ADC3_IRQHandler

    .word    0

...

  .weak  ADC3_IRQHandler

  .thumb_set ADC3_IRQHandler,Default_Handler

...

I put a breakpoint into the default handler but it doesn't get stuck there.

The ADC1 I'm using in parallel with the same configuration works fine though.

Here is the initialization code:

int32_t InitADC( void ) {

    ADC_InitTypeDef ADC_InitStructure;

    /* PCLK2 is the APB2 clock */

   

    RCC_ADCCLKConfig(RCC_PCLK2_Div8);

    /* Enable ADC1 clock so that we can talk to it */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

    // ADC 1

    /* Put everything back to power-on defaults */

    ADC_DeInit(ADC1);

    ADC_StructInit(&ADC_InitStructure);

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

    /* Disable the scan conversion so we do one at a time */

    ADC_InitStructure.ADC_ScanConvMode = DISABLE;

    /* Don't do continuous conversions - do them on demand */

    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

    /* Start conversion by software, not an external trigger */

    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

    /* Conversions are 12 bit - put them in the lower 12 bits of the result */

    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

    /* Say how many channels would be used by the sequencer */

    ADC_InitStructure.ADC_NbrOfChannel = 1;

    /* Now do the setup */

    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

    ADC_RegularChannelConfig(ADC1,ADC_Channel_2,1,ADC_SampleTime_7Cycles5);

    // ADC3

    ADC_DeInit(ADC3);

    ADC_StructInit(&ADC_InitStructure);

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

    /* Disable the scan conversion so we do one at a time */

    ADC_InitStructure.ADC_ScanConvMode = DISABLE;

    /* Don't do continuous conversions - do them on demand */

    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

    /* Start conversion by software, not an external trigger */

    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

    /* Conversions are 12 bit - put them in the lower 12 bits of the result */

    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

    /* Say how many channels would be used by the sequencer */

    ADC_InitStructure.ADC_NbrOfChannel = 1;

    /* Now do the setup */

    ADC_Init(ADC3, &ADC_InitStructure);

    ADC_ITConfig(ADC3, ADC_IT_EOC, ENABLE);

    ADC_RegularChannelConfig(ADC3,ADC_Channel_9,1,ADC_SampleTime_7Cycles5);

    /* Enable ADC1 */

    ADC_Cmd(ADC1, ENABLE);

    /* Enable ADC3 */

    ADC_Cmd(ADC3, ENABLE);

    /* Enable ADC1 reset calibaration register */

    ADC_ResetCalibration(ADC1);

    /* Check the end of ADC1 reset calibration register */

    while( ADC_GetResetCalibrationStatus(ADC1) ){

    }

    /* Start ADC1 calibaration */

    ADC_StartCalibration(ADC1);

    /* Check the end of ADC1 calibration */

    while( ADC_GetCalibrationStatus(ADC1) ) {

    }

    /* Enable ADC3 reset calibaration register */

    ADC_ResetCalibration(ADC3);

    /* Check the end of ADC3 reset calibration register */

    while( ADC_GetResetCalibrationStatus(ADC3) ){

    }

    /* Start ADC3 calibaration */

    ADC_StartCalibration(ADC3);

    /* Check the end of ADC3 calibration */

    while( ADC_GetCalibrationStatus(ADC3) ) {

    }

    // TODO: consider timeouts for calibration waits

    ADC_SoftwareStartConvCmd(ADC1,ENABLE);

    ADC_SoftwareStartConvCmd(ADC3,ENABLE);

    return 0;

}

uint16_t ADC1ConvertedValue=0;

uint16_t ADC3ConvertedValue=0;

void ADC1_IRQHandler(void) {

     ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);

   

      ADC1ConvertedValue = ADC_GetConversionValue(ADC1);

}

void ADC3_IRQHandler(void) {

    ADC_ClearITPendingBit(ADC3, ADC_IT_EOC);

     

    ADC3ConvertedValue = ADC_GetConversionValue(ADC3);

}

3 REPLIES 3
frankmeyer9
Associate II
Posted on February 28, 2014 at 13:30

According to this:

http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1031/LN1566/PF216819

your mentioned MCU has only one ADC.

kt1023
Associate
Posted on February 28, 2014 at 14:19

Right! I suppose I have to use something like scan mode or single sampling of adc channels then.

Thanks.

frankmeyer9
Associate II
Posted on February 28, 2014 at 16:39

Not sure, but I guess you got something wrong.

The device you mentioned has just one ADC, but this ADC has several channels. The basic difference is - all those channels can only be converted sequentially by one ADC, while separate ADCs can run conversions concurrently.

If I remember correctly, the F1 ADC works up to 400ksps, far enough for a lot of applications.

For the actual available channels and pin mappings of your MCU, consult the reference manual and datasheet.