#define RCC_BASE 0x40021000
#define ADC_BASE 0x40012400
#define RCC_APBENR2 (*((volatile uint32_t*)(RCC_BASE + 0x40)))
#define ADC_ISR (*((volatile uint32_t*)(ADC_BASE + 0x00)))
#define ADC_CR (*((volatile uint32_t*)(ADC_BASE + 0x08)))
#define ADC_CFGR2 (*((volatile uint32_t*)(ADC_BASE + 0x10)))
#define ADC_SMPR (*((volatile uint32_t*)(ADC_BASE + 0x14)))
#define ADC_CHSELR (*((volatile uint32_t*)(ADC_BASE + 0x28)))
#define ADC_DR (*((volatile uint32_t*)(ADC_BASE + 0x40)))
#define RCC_APBENR2_ADCEN (1<<20)
#define ADC_CR_ADEN (1<<0)
#define ADC_CR_ADCAL (1<<31)
#define ADC_CFGR2_CKMODE (1<<30)
#define ADC_CHSELR_CHSEL0 (1<<0)
#define ADC_SMPR_SMP_1_5 0 //(0<<0);
#define ADC_CR_ADSTART (1<<2)
#define ADC_ISR_ADRDY (1<<0)
#define ADC_ISR_EOC (1<<2)
void ADC_Init(void) {
// Enable ADC clock
RCC_APBENR2 |= RCC_APBENR2_ADCEN;
// Calibrate ADC
ADC_CR &= ~ADC_CR_ADEN; // Ensure ADC is disabled
ADC_CR |= ADC_CR_ADCAL; // Start calibration
while (ADC_CR & ADC_CR_ADCAL); // Wait for calibration to complete
// Configure ADC
ADC_CFGR2 &= ~ADC_CFGR2_CKMODE; // Use HCLK/1
ADC_CHSELR = ADC_CHSELR_CHSEL0; // Select channel 0
ADC_SMPR = ADC_SMPR_SMP_1_5; // Set sampling time to 1.5 ADC clock cycles
// Enable ADC
ADC_CR |= ADC_CR_ADEN; // Enable ADC
while (!(ADC_ISR & ADC_ISR_ADRDY)); // Wait until ADC is ready
}
uint16_t ADC_Read(void) {
ADC_CR |= ADC_CR_ADSTART; // Start conversion
while (!(ADC_ISR & ADC_ISR_EOC)); // Wait for conversion to complete
return ADC_DR; // Return the ADC result
}
int main(void) {
ADC_Init(); // Initialize ADC
Serial.begin(115200);
while (1) {
uint16_t adc_value = ADC_Read(); // Read ADC value
// Use adc_value (e.g., for processing or debugging)
Serial.println(adc_value);
}
}