2021-05-30 02:12 PM
Hi.
I am having problems with the ADC, for some reason, it only works when I put a breakpoint in the function I use to enable the ADC to debug, but, if I run it without any breakpoint, it does not work.
line of code I use to extract a value from the ADC:
sensor_val = periph::ADC12::adc12_get_value();
That function is this one:
static std::uint32_t adc12_get_value(){
//Start conversion
*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) |= (1U << 2); //ADC Start
while(!*reinterpret_cast<volatile std::uint32_t *> (adc1_isr) & (1U << 2)){} //End of convertion
return *reinterpret_cast<volatile std::uint32_t *> (adc1_dr); //extract value
}
and this is the rest of the functions I use for calibration and initialization:
static void adc12_calib_single(){
//Calibrate the ADC
adc12_disable();
*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) &= ~(1U << 30);
*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) |= (1U << 31);
while((*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) & (1U << 31)) != 0){}
}
static void adc12_enable_regulator(){
RCC->CFGR2 |= (0x16 << 4);
RCC->AHBENR |= (1 << 28);
//enable the regulator for the ADC
*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) = 0;
*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) |= (0x1 << 28);
periph::SYSTICK::delay_us(10);
}
static void adc12_disable(){
*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) |= (1U << 1);
while(*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) & (1U << 0)){}
}
static void adc12_init(){
RCC->AHBENR |= (1 << 28);
//channel 1 with lengnght of 1
*reinterpret_cast<volatile std::uint32_t *> (adc1_sqr1) = 0;
*reinterpret_cast<volatile std::uint32_t *> (adc1_sqr1) |= (1U << 6);
*reinterpret_cast<volatile std::uint32_t *> (adc1_cfgr) |= (1U << 13);
//enable ADC
*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) |= (1U << 0);
while(!*reinterpret_cast<volatile std::uint32_t *> (adc1_isr) & (1U << 0)){}
adc12_get_value();
adc12_calib_single();
*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) |= (1U << 0);
while(!*reinterpret_cast<volatile std::uint32_t *> (adc1_isr) & (1U << 0)){}
}
Thanks in advance
2021-05-30 06:45 PM
> it does not work
What does this mean in particular? Where is the code stuck?
Consider using the standard CMSIS headers to make the code more readable.
*reinterpret_cast<volatile std::uint32_t *> (adc1_cr) |= (1U << 2); //ADC Start
vs.
ADC1->CR |= ADC_CR_ADSTART;
2021-05-31 03:13 AM
Hi @Juan Martín Castillo ,
Please refer to ADC examples of the STM32CubeF3; under directory: Projects\STM32F303RE-Nucleo\Examples\ADC
Best Regards,
Ons.
2021-05-31 08:19 AM
Hi! well, when I try to debug the variable (without using the breakpoint) it just does not take any value (is like is jumping that function of enabling the ADC). And well, I will try to use the CMSIS, to check.
Thanks for the answer.
2021-05-31 08:20 AM
Hi! thanks, I will check it later!
Thanks for the answer
2021-06-05 05:48 AM
Hi TDK, sorry if I bother you, but I fixed the problem but is strange, I used CMSIS as you suggested and wasn't working but, I changed something:
RCC->AHBENR |= (1 << 28)
I had that line of code to activate the ADC1 and ADC2 and the ADC wasn't working, so I changed it using the macros that the CMSIS library provides:
RCC->AHBENR |= RCC_AHBENR_ADC12EN;
and it worked, that RCC_AHBENR_ADC12EN is the same as (1U << 28U), the only difference is the "U" after the numbers, that makes any difference? like I know that "U" means is an unsigned number, but I don't know if that's a problem if i don't put it
Thanks a lot.
2021-06-05 06:07 AM
Ok, nvm, i have seen that it is 0x1U << 0x28, hum, is strange, anyways, thanks for the answer
2021-06-05 06:52 AM
One of the major reasons to use the provided CMSIS headers is to eliminate typos like this.
Still not sure what "does not take any value" can possibly mean.