#include <stm32c011xx.h>
// global variables can be read by cortex-debug live watch or STM32CubeMonitor
uint32_t adc_data_raw; // raw 12-bit ADC result
uint32_t adc_data_mV; // in millivolt
int main(void)
{
RCC->IOPENR |= RCC_IOPENR_GPIOAEN; // enable peripheral clock
(void)RCC->IOPENR; // read back to make sure that clock is on
// Set PA8 to analog input mode (mode 3) for ADC, other regs defaults are okay
GPIOA->MODER = (GPIOA->MODER & ~GPIO_MODER_MODE8_Msk) | (3 << GPIO_MODER_MODE8_Pos);
// let ADC (digital block) be clocked by: SYSCLK
RCC->CCIPR = (RCC->CCIPR &~RCC_CCIPR_ADCSEL_Msk) | (0<<RCC_CCIPR_ADCSEL_Pos);
RCC->APBENR2 |= RCC_APBENR2_ADCEN; // turn ADC clock on
(void)RCC->APBENR2; // read back to make sure that clock is on
ADC1->CR |= ADC_CR_ADVREGEN; // power up ADC voltage regulator
// wait t_ADCVREG_STUP (ADC voltage regulator start-up time),
for(volatile int i=0; i<12*20; ++i); // min 20 µs see data sheet
// do self calibration
ADC1->CR |= ADC_CR_ADCAL;
while(ADC1->CR & ADC_CR_ADCAL); // wait for calibration to finish
uint8_t calibration_factor = ADC1->DR;
ADC1->CFGR1 = 0; // default config after reset
ADC1->CFGR2 = 0; // default config after reset
ADC1->SMPR = 0; // sampling time register, default after reset
// "enable the ADC" procedure from RM0490 Rev 3:
ADC1->ISR |= ADC_ISR_ADRDY; // Clear the ADRDY bit in ADC_ISR register
ADC1->CR |= ADC_CR_ADEN; // Set ADEN = 1 in the ADC_CR register.
while(!(ADC1->ISR & ADC_ISR_ADRDY)); // Wait until ADRDY = 1 in the ADC_ISR register
ADC1->CALFACT = calibration_factor;
// above: CHSELRMOD = 0 in ADC_CFGR1, so every channel has a bit. set bit to activate that channel
ADC1->CHSELR = ADC_CHSELR_CHSEL8; // select channel ADC_IN8 which is PA8 connected to joystick
while(!(ADC1->ISR & ADC_ISR_CCRDY)); // wait until channel configuration update is applied
uint32_t Vdda_mV = 3300; // there are better ways to estimate Vdda
while(1) {
ADC1->CR |= ADC_CR_ADSTART; // start ADC conversion
while(!(ADC1->ISR & ADC_ISR_EOC)); // wait for end of conversion
adc_data_raw = ADC1->DR; // conversion done. store result
adc_data_mV = (adc_data_raw * Vdda_mV) / 4095; // Vdda == 4095 digital reading
}
}
hth
KnarfB