cancel
Showing results for 
Search instead for 
Did you mean: 

Couldn't get any ADC value with STM32H573 ADC

B.Redmoon
Associate II

I need help. I couldn't get any adc value whether with live expressions or UART . UART is working fine so the problem is within the ADC configuration code. have i miss or overcomplicated anything?

 

#include "stdio.h" #include "stdint.h" #include "stm32h573xx.h" #include "uart.h" //volatile uint16_t sensor_value; __IO uint16_t sensor_value; void PA4_PA5_ADC_Init(void) { //RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; //Enable Clock for GPIOA GPIOA->MODER &= ~((3U << (4 * 2)) | (3U << (5 * 2))); //Reset PA4 & PA5 GPIOA->MODER |= ((3U << (4 * 2)) | (3U << (5 * 2))); //Set PA4 & PA5 as analog input GPIOA->PUPDR &= ~((3U << (4 * 2)) | (3U << (5 * 2))); //Set no pullup or pulldown } void adcclk_init(void){ // Configure ADC clock source // //hsi_ck selected as system clk in uart.c // RCC->AHB2ENR |= (1U << 10); //Enable ADC Clock RCC->CCIPR5 &= ~(7U << 0); // Clear ADCSEL bits; rcc_hclk as clock source (default after reset) RCC->CCIPR5 |= (1U<<0); //sys_ck slected as kernel clk for ADC ADC12_COMMON->CCR &= ~(0x1F<<0); //Set ADC1 and ADC2 to independent mode ADC12_COMMON->CCR &= ~(15U<<18); //PRESC[3:0] | ADC prescaler; Input ADC clock not divided ADC12_COMMON->CCR &= ~(3U<<16); //CKMODE[1:0] | 00 ADC clock scheme: adc_ker_ck ADC12_COMMON->CCR |= (1U<<16); //CKMODE[1:0] | 01 ADC clock scheme: adc_hclk/1 //This configuration must be enabled only if the AHB clock prescaler is set to 1 (HPRE[3:0] = 0XXX in RCC_CFGR register) //and if the system clock has a 50% duty cycle. RCC_CFGR HPRE[3:0] wasset in uart.c } void adcinit(void) { VREFBUF->CSR &= ~(7U<<4); //Set to VREFBUF0 // Enable VREFBUF VREFBUF->CSR &= ~(1U<<1); //Set HIZ to 0 VREFBUF->CSR &= ~(1U<<0); VREFBUF->CSR |= (1U<<0); //Set ENVR to 1 while (!(VREFBUF->CSR & VREFBUF_CSR_VRR)) {} //while (!(VREFBUF->CSR & (1U<<3))) {} //Wait until Voltage ref buffer output has stabilized. ADC1->SMPR2 &= ~(7U <<24); // Set ADC CH18 sample time to 2.5ADC cycles ADC1->DIFSEL |= (1U << 18); // Set ADC Channel 18 as diff. mode (PA4 is INP18 while PA5 is INN18) //ADC1->DIFSEL &= ~(1U << 18); // Set ADC Channel 18 as single-ended mode (PA4 is INP18 while PA5 is INN18) ADC1->SQR1 &= ~(15U << 0); // Set Seq length to single conversion ADC1->SQR1 &= ~(31U << 6); // Clear bits 6-10 ADC1->SQR1 |= (18U << 6); // Write 18 (dec) on bits 6-10 to set Channel 18 as the 1st sequence for ADC conversion ADC1->CFGR &= ~((1U << 11) | (1U << 10)); // Select sw trigger for ADC conversion ADC1->CFGR &= ~((1U << 4) | (1U << 3)); // Set 12-bit resolution (default) ADC1->CFGR &= ~(1U << 15); // Set to right alignment ADC1->CFGR |= ADC_CFGR_CONT; // Set ADC to continuous mode ADC1->CFGR |= ADC_CFGR_OVRMOD; // Set ADC to overwrite when register is full ADC1->CR &= ~ADC_CR_DEEPPWD; // Take ADC voltage regulator out of deep power down mode ADC1->CR |= ADC_CR_ADVREGEN; // Enable ADC regulator for (volatile int i = 0; i < 10000; i++); // Implement delay > TADCVREG_STUP which is 10us ADC1->ISR &= ~(1U << 4); // Clear OVR status ADC1->ISR &= ~(1U << 3); // Clear EOS status ADC1->CR &= ~ADC_CR_ADDIS; // Clear ADC disable command } // void start_conversion(void) { ADC1->ISR &= ~ADC_ISR_ADRDY; // Clear ADC ready status ADC1->CR |= ADC_CR_ADEN; // Enable ADC for (volatile int i = 0; i < 10000; i++); // Small delay while (!(ADC1->ISR & ADC_ISR_ADRDY)) {} for (volatile int i = 0; i < 10000; i++); // Small delay ADC1->CR |= ADC_CR_ADSTART; // Start conversion } uint16_t ADC_Read(void) { int timeout = 1000000; while (!(ADC1->ISR & ADC_ISR_EOC)) { //if End of Conversion is reached //if (--timeout == 0) { // printf("ADC Timeout! \n\r"); // return 0; //} } return (uint16_t)ADC1->DR; } int main(void) { RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN; usart1_rxtx_init(); PA4_PA5_ADC_Init(); adcclk_init(); adcinit(); while(1) { start_conversion(); sensor_value = ADC_Read(); printf("Sensor Value: %d \n", sensor_value); //usart1_write('Y'); //printf("UART is working fine........\n\r"); for (volatile int i = 0; i < 100000; i++); printf("UART is working fine........\n\r"); } }
View more

 

2 REPLIES 2
B.Redmoon
Associate II

anybody?

Hello,

Better to start by using the HAL and inspire from the examples provided in STM32CubeH5 package:
https://github.com/STMicroelectronics/STM32CubeH5/tree/main/Projects/NUCLEO-H563ZI/Examples/ADC
Or simply start by using CubeMX to generate the code base on your configuration.
Then if you succeed with that you can inspire from the HAL implementation to develop your specific direct access to the registers.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.