cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7A3ZI-Q getting random values from ADC

ikok07
Associate

Hello, I'm currently trying to develop a bare-metal ADC driver for my Nucleo STM32H7A3ZI-Q Board. I have done all the necessary steps in order to setup the ADC, however I still get random values from the data register, even though I have my PF11 (or A5) connected to the GND.

Here is my current code:

#define ADC1EN					(1U<<5)
#define GPIOFEN					(1U<<5)
#define ADC_CH2					(1U<<7)
#define ADC_SEQ_LEN_1			        (0x00)

#define ADC_DEEPPWDEN			        (1U<<29)
#define ADC_REGEN				(1U<<28)
#define ADC_LDORDY				(1U<<12)
#define ADC_PRESC_2				(1U<<18)
#define ADC_CKMODE_SCLK_1		        (2U<<16)
#define ADC_ADCALDIF			        (1U<<30)
#define ADC_ADCALLIN			        (1U<<16)
#define ADC_ADCAL				(1U<<31)
#define ADC_ADEN				(1U<<0)
#define ADC_ADSTART				(1U<<2)
#define ADC_ADRDY				(1U<<0)

#define ADC_EOC					(1U<<2)

void pf11_adc_init(void) {

	// Configure the ADC GPIO pin

	RCC->AHB4ENR |= GPIOFEN; 				// Enable clock access to GPIOF
	GPIOF->MODER |= (1U<<23) | (1U<<22); 	// Set mode of PF11 to analog

	// Configure the ADC module

	RCC->AHB1ENR |= ADC1EN; // Enable clock access to ADC1

	// Conversion sequence start
	ADC1->SQR1 = ADC_CH2;

	// Conversion sequence length
	ADC1->SQR1 |= ADC_SEQ_LEN_1;

	// Disable ADC deep-power-down mode
	ADC1->CR &=~ ADC_DEEPPWDEN;

	// Start the voltage regulator
	ADC1->CR |= ADC_REGEN;

	// Wait for the regulator to start up
	while (!(ADC1->ISR & ADC_LDORDY)) {}

	// Select prescaler -> 2
//	ADC12_COMMON->CCR |= ADC_PRESC_2;

	// Select kernel clock (derive from AHB clock)
	ADC12_COMMON->CCR |= ADC_CKMODE_SCLK_1;

	// Set single-ended calibration mode
	ADC1->CR &=~ ADC_ADCALDIF;

	// Enable linearity calibration
	ADC1->CR |= ADC_ADCALLIN;

	// Start ADC calibration
	ADC1->CR |= ADC_ADCAL;

	// Wait for calibration to finish
	while (ADC1->CR & ADC_ADCAL) {}

	// Enable the ADC module
	ADC1->ISR |= ADC_ADRDY; // clear ready state
	ADC1->CR |= ADC_ADEN;

	// Wait for the ADC to be ready
	while (!(ADC1->ISR & ADC_ADRDY)) {}
}

void start_conversion(void) {

	// Start the ADC conversion
	ADC1->CR |= ADC_ADSTART;
}

uint32_t adc_read(void) {
	// Wait for conversion to be complete
	while (!(ADC1->ISR & ADC_EOC)) {}

	// Read converted result
	return ADC1->DR;
}

 

0 REPLIES 0