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");
	}

}

 

0 REPLIES 0