cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G431 ADC Wont Calibrate and wont work

LLOLO.1
Associate II

Hi I am currently working on a project where I have to use single channel ADC with continuous conversion mode of STM32G431KB on NUCLEO board. However my code stucks at while loop where calibration needs to happen. Also I noticed that ADC12_Common register do not take value of 0b0001 which is divide clock by two. I am giving 42.5MHz ADC from PLLP divider and was planning to divide it by 2.

#include "main.h"
#include "SysClock_Config.h"
 
 
void DummyDelay(int x)
{
	int temp = x;
	while(temp)
	{
		temp--;
	}
}
 
void Initialization(void)
{
	RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN | RCC_AHB2ENR_ADC12EN;
 
	GPIOB->MODER |= GPIO_MODER_MODER0; //Set PB0 as Analog
 
	ADC12_COMMON->CCR |= (0b0001 << ADC_CCR_PRESC_Pos); //ADC Clock divided by 2
	ADC1->CR &= ~(ADC_CR_DEEPPWD); //Disable ADC Deep-Power-Down mode
	ADC1->CR |= ADC_CR_ADVREGEN; //Enable ADC Voltage Regulator
	DummyDelay(5000);
	ADC1->CR &= ~(ADC_CR_ADEN); //Disable ADC
	ADC1->CR &= ~(ADC_CR_ADCALDIF); //Single Ended Mode Calibration
	ADC1->CR |= ADC_CR_ADCAL; //Start Calibration
	while(ADC1->CR & ADC_CR_ADCAL); //Wait Until Calibration Complete
 
 
 
	ADC1->CFGR |= ADC_CFGR_CONT; //ADC continuous mode
	ADC1->CFGR &= ~(ADC_CFGR_RES); //12-bit ADC
	ADC1->SQR1 |= (1 << ADC_SQR1_L_Pos) | (15 << ADC_SQR1_SQ1_Pos); // Only 1 conversion for ADC channel 15
 
	ADC1->CR |= ADC_CR_ADEN; //Enable ADC
	while(!(ADC1->ISR & ADC_ISR_ADRDY)); //Wait Until ADC Enables
 
 
}
 
 
 
 
int main(void)
{
 
  HAL_Init();
  SystemClock_Config();
 
  Initialization();
 
  ADC1->CR |= ADC_CR_ADSTART; //Start ADC Sampling/Conversion Sequence
 
 
 
  while (1)
  {
 
  }
 
}
 
#include "main.h"
 
void Error_Handler(void)
{
 
}
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV6;
  RCC_OscInitStruct.PLL.PLLN = 85;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV8;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8) != HAL_OK)
  {
    Error_Handler();
  }
 
  SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk);
 
}

NOTE: I am using STM32CubeIDE.

4 REPLIES 4
TDK
Guru

Why not use the cubemx generated code to initialize the adc as well? Probably just missing something.

If you feel a post has answered your question, please click "Accept as Solution".
LLOLO.1
Associate II

I don't like cubemx generating everything sometimes it gets buggy. Is there someone who programmed STM32G4 at register level?

TDK
Guru

> I don't like cubemx generating everything sometimes it gets buggy.

Who has the buggy code now?

Like it or not, pretty much all software has bugs. Even if you don't want to use CubeMX, the code it generates can be helpful for figuring out what you're doing wrong.

In this case, your clock initialization is different from what HAL does. Depending on your compiler settings, it may be a problem, or it may not.

This is from the H7, but I'm sure the G4 code is similar:

#define __HAL_RCC_ADC12_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ADC12EN);\
                                        /* Delay after an RCC peripheral clock enabling */ \
                                        tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_ADC12EN);\
                                        UNUSED(tmpreg); \
                                       } while(0)

If you feel a post has answered your question, please click "Accept as Solution".
rclar.6
Senior

I have sometimes had to give the ADCs more time to convert. Try adding longer pre-scale times