cancel
Showing results for 
Search instead for 
Did you mean: 

ADC implementation in LL can only read 3 values ?

chato.1
Associate

Hello,

I am trying to implement an ADC init and read in interrupt mode.

I have a very basic setup where I read an analog entry from a potentiometer and print its raw converted value.

When I first implemented it with HAL, I had no issue and could read values that smoothly evolved from 0 et 65535 (16 Bits) as I tweaked the potentiometer.

Then I tried reimplementing my code using the Low Layer (LL) Library and as I read from the ADC, I can only read 3 values: 32767, 49151, 65535.

Here is a snippet of my code :

void ADC_Init(void)
{
	LL_ADC_InitTypeDef ADC_InitStruct = {0};
	LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
	LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0};
 
	LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
 
	LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLL2P);
 
	// Peripheral clock enable
	LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_ADC12);
 
	//ADC1 GPIO Configuration
	LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA);
	GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7;
	GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
	GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
	LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
	// ADC1 interrupt Init
	NVIC_SetPriority(ADC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
	NVIC_EnableIRQ(ADC_IRQn);
	LL_ADC_EnableIT_EOC(ADC1);
 
	// Common config
	LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE);
	ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_16B;
	ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE;
	LL_ADC_Init(ADC1, &ADC_InitStruct);
	ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
	ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_DISABLE;
	ADC_REG_InitStruct.SequencerDiscont = DISABLE;
	ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE;
	ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;
	LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
	ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV1;
	ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT;
	LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct);
 
	LL_ADC_DisableDeepPowerDown(ADC1);
	LL_ADC_EnableInternalRegulator(ADC1);
	uint32_t wait_loop_index;
	wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
	while(wait_loop_index != 0)
	{
	  wait_loop_index--;
	}
 
	// Configure Regular Channel
	LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_3);
	LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_3, LL_ADC_SAMPLINGTIME_1CYCLE_5);
	LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_3, LL_ADC_SINGLE_ENDED);
}
 
void ADC_IRQHandler(void)
{
  // Check if the end of conversion flag is set
  if (LL_ADC_IsActiveFlag_EOC(ADC1))
  {
	  LL_ADC_ClearFlag_EOC(ADC1);
	  AD_RES = LL_ADC_REG_ReadConversionData16(ADC1);
  }
 
}
 
int main(void)
{
 
  HAL_Init();
 
  SystemClock_Config();
 
  PeriphCommonClock_Config();
 
  MX_GPIO_Init();
  MX_USART3_UART_Init();
  MX_USB_OTG_HS_USB_Init();
 
  ADC_Init();
  LL_ADC_SetChannelPreSelection(ADC1, LL_ADC_CHANNEL_3);
  LL_ADC_Enable(ADC1);
  while (LL_ADC_IsActiveFlag_ADRDY(ADC1) == 0);
 
  while (1)
  {
    LL_ADC_REG_StartConversion(ADC1);    
    char adc_string[32];
    sprintf(adc_string, "The value of ADC is  : %d \n\r", AD_RES);
    HAL_UART_Transmit(&huart3, adc_string, sizeof(adc_string), 1000);
  }
 
}

Thank you for your help.

1 REPLY 1

Which STM32?

Place breakpoint into the ADC and read out the ADC registers' content there using debugger. Still only 3 values?

Try comparing to working case.

JW