cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F302 change ADC clocksource

Clemens Ehm
Associate II
Posted on January 12, 2018 at 09:39

Hey,

in my current ADC code I use the PLL as clock source (72MHz). That causes a problem in the powersave mode, where the PLL is disabled and the clock source of the mcu core is just HSE (12 MHz).

Now I want to use the AHB clock instead of the PLL clock but it's simply not working.

Here an overview of my current pll adc code:

[code]

    //GPIO Init

    RCC->AHBENR |= RCC_AHBENR_GPIOAEN ;

    GPIOA->MODER |= GPIO_MODER_MODER0;

    //CLK Init

    RCC->CFGR2 |= RCC_CFGR2_ADCPRE12_DIV8; //PLL Clk / 4

    RCC->AHBENR |= RCC_AHBENR_ADC12EN;

    //Calibration

    ADC1->CR &= ~ADC_CR_ADVREGEN;

    ADC1->CR |= ADC_CR_ADVREGEN_0;

    ADC1->CR &= ~ADC_CR_ADCALDIF;

    ADC1->CR |= ADC_CR_ADCAL;

    while (ADC1->CR & ADC_CR_ADCAL);

    set_saved_vref_cal_value( *((volatile t_u16*)(0x1FFFF7BA)));

    //Enable ADC

    do

    {

        ADC1->CR |= ADC_CR_ADEN;

    } while ((ADC1->ISR & ADC_ISR_ADRD) == 0);

    //Config ADC

    ADC1->CFGR &= ~ADC_CFGR_RES; //12bit resolution

    ADC1->CFGR |= ADC_CFGR_CONT; //ADC_ContinuousConvMode_Enable

    ADC1->CFGR &= ~ADC_CFGR_ALIGN; // Right data alignment

    ADC1->SQR1 |= ADC_SQR1_SQ1_0; //ADC Channel In1 (PA0)

    ADC1->SQR1 |= ADC_SQR1_SQ2_4; //ADC Channel 16 Temperature Sensor

    ADC1->SQR1 |= ADC_SQR1_SQ3_4 | ADC_SQR1_SQ3_1; //ADC Channel 18 VRef Voltage

    ADC1->SQR1 &= ~ADC_SQR1_L; // reset active channels

    ADC1->SQR1 |= ADC_SQR1_L_1 | ADC_SQR1_L_0; //Set active channel count to 3

    ADC1_2->CCR = ADC12_CCR_VREFEN | ADC12_CCR_TSEN;

    ADC1->SMPR1 |= ADC_SMPR1_SMP0_2 | ADC_SMPR1_SMP0_1 | ADC_SMPR1_SMP0_0; //Sampling

    ADC1->SMPR2 |= ADC_SMPR2_SMP16_2 | ADC_SMPR2_SMP16_1 | ADC_SMPR2_SMP16_0;

    ADC1->SMPR2 |= ADC_SMPR2_SMP18_2 | ADC_SMPR2_SMP18_1 | ADC_SMPR2_SMP18_0;

    ADC1->IER  =  ADC_IER_EOC;

    NVIC_SetPriority(ADC1_IRQn, 0);

    NVIC_EnableIRQ(ADC1_IRQn);

[/code]

I tried a lot with the clk init part without success. As I saw in the manuel the RCC->CFGR2 must be set to zero (bits 8:4) to use the AHB clock. I also change the ADC1_2->CCR Register and use CKMode - but it's not working, the adc always stuck at the init part.

Could someone please show me how to use the AHB clock?

#adc-clock #enable-adc #pll #ahb #stm32-f3
4 REPLIES 4
Zt Liu
Senior III
Posted on January 15, 2018 at 05:34

Hi, not very sure what do you mean. 

ADC clock is only 

asynchronous

 or 

synchronous

 with the AHB clk. 

AHB clock itself is not for sampling and conversion.

Note that in your Enable ADC part of code,

you check the 

ADC_ISR_ADRD flag.

If you want to do this, make sure your set the interrupt flag 

ADRDYIE too.

Otherwise you just wait for few usec for ADC to get stablized.

Good Luck!

.Zt

Clemens Ehm
Associate II
Posted on February 02, 2018 at 17:11

Well to make it short and simple:

- In 'normal mode' I use the PLL (72MHz) and everything works fine

- In my 'powersave mode', I disable the PLL to save energy and the MCU uses the HSE source (12 MHz) -> ADC not working anymore

So the question is how to fix/change the code that the ADC is working with source HSE @12MHz?

Posted on February 04, 2018 at 08:49

Reset and clock stop the ADC just before you change the ADC clock, and after the clock source being stable and changed, configure the ADC from scratch as it was done the first time after power on reset.

For test: check if you can boot and start the ADC after power on reset in 12MHz mode. If it doesn't debug first this step.

Posted on February 05, 2018 at 16:41

Well the ADC is not running. I try to init the ADC directly after mcu reset.

- PLL is diabled, AHB/HCLK is my HSE Clk / 4 (3 MHz)

- I use the define ADC12_CCR_CKMODE_1, because manuel says: 'This configuration must be enabled only if the AHB clock prescaler is set to 1'. So I try to use ADC12_CCR_CKMODE_1 but ofc no success.

    RCC->CFGR2 &= RCC_CFGR2_ADCPRE12_NO;

    ADC1_2->CCR |= ADC12_CCR_CKMODE_1;

    RCC->AHBENR |= RCC_AHBENR_ADC12EN;

(also tried it with some small delays between the commands to be sure enough time to startup)