cancel
Showing results for 
Search instead for 
Did you mean: 

L031K6 : ADC value is not similar as real value

DU2
Associate II

I get 12bit ADC data from DMA multi channel.

and when I get it , I use this formula to get ADC measure.

adc input (0-4095) * 3300 / 4095

but This result usually have different from real measurement, about 100-200mV.

In that case, Is there better way to correct data by other methode ?

here is my configuration codes.

I set adcBuffer[4] for get ADC-DMA data.

When I init like that, I use HAL_ADC_ConvCpltCallback for receiving .

--------------------------------------------------------------------------------------------------------------------------

static DMA_HandleTypeDef     DmaHandle;
 
  
 
 /*##-1- Enable peripherals and GPIO Clocks #################################*/
 
 /* Enable GPIO clock ****************************************/
 
 __HAL_RCC_GPIOA_CLK_ENABLE();
 
 /* ADC1 Periph clock enable */
 
 //ADCx_CLK_ENABLE();
 
 /* Enable DMA1 clock */
 
 __HAL_RCC_DMA1_CLK_ENABLE();
 
 
 
 
 
  
 
 /*********************** Configure DMA parameters ***************************/
 
 DmaHandle.Instance         = DMA1_Channel1;
 
 DmaHandle.Init.Direction      = DMA_PERIPH_TO_MEMORY;
 
 DmaHandle.Init.PeriphInc      = DMA_PINC_DISABLE;
 
 DmaHandle.Init.MemInc       = DMA_MINC_ENABLE;
 
 DmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
 
 DmaHandle.Init.MemDataAlignment  = DMA_MDATAALIGN_HALFWORD;
 
 DmaHandle.Init.Mode        = DMA_CIRCULAR;
 
 DmaHandle.Init.Priority      = DMA_PRIORITY_MEDIUM;
 
 DmaHandle.Init.Request       = DMA_REQUEST_0;
 
 /* Deinitialize & Initialize the DMA for new transfer */
 
 HAL_DMA_DeInit(&DmaHandle);
 
 HAL_DMA_Init(&DmaHandle);
 
  
 
 /* Associate the DMA handle */
 
 __HAL_LINKDMA(&hadc, DMA_Handle, DmaHandle);
 
 
 
 /* NVIC configuration for DMA Input data interrupt */
 
 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 0);
 
 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
 
  
 
 /* USER CODE BEGIN ADC_Init 0 */
 
 
 
 /* USER CODE END ADC_Init 0 */
 
 
 
 ADC_ChannelConfTypeDef sConfig = {0};
 
 
 
 /* USER CODE BEGIN ADC_Init 1 */
 
 
 
 /* USER CODE END ADC_Init 1 */
 
 /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
 
 */
 
 hadc.Instance = ADC1;
 
 hadc.Init.OversamplingMode = DISABLE;
 
 hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; //need to be 2?
 
 hadc.Init.Resolution = ADC_RESOLUTION_12B;
 
 hadc.Init.SamplingTime = ADC_SAMPLETIME_79CYCLES_5; 
 
  //ADC_SAMPLETIME_79CYCLES_5; //7 _ 5 ?
 
 hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
 
 hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 
 hadc.Init.ContinuousConvMode = ENABLE;
 
 hadc.Init.DiscontinuousConvMode = DISABLE;
 
 hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
 
 hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
 
 hadc.Init.DMAContinuousRequests = ENABLE;
 
 hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
 
 hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
 
 hadc.Init.LowPowerAutoWait = DISABLE;
 
 hadc.Init.LowPowerFrequencyMode = DISABLE;
 
 hadc.Init.LowPowerAutoPowerOff = DISABLE;
 
 
 
  
 
  
 
  
 
 if (HAL_ADC_Init(&hadc) != HAL_OK)
 
 {
 
  Error_Handler();
 
 }
 
  
 
 /* ### - 2 - Start calibration ############################################ */
 
 if (HAL_ADCEx_Calibration_Start(&hadc , ADC_SINGLE_ENDED) != HAL_OK)
 
 {
 
  Error_Handler();
 
 }
 
  
 
  /** Configure for the selected ADC regular channel to be converted. 
 
 */
 
 sConfig.Channel =  ADC_CHANNEL_1 | ADC_CHANNEL_3 | ADC_CHANNEL_8 | ADC_CHANNEL_TEMPSENSOR ; //tempsensor == ch 18 !
 
 sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; //ranked by channel number
 
  
 
  
 
  
 
 if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
 
 {
 
  Error_Handler();
 
 }
 
  
 
 /* USER CODE BEGIN ADC_Init 2 */
 
  
 
  
 
  
 
 
 
 /* if (HAL_ADC_Start(&hadc ) != HAL_OK)
 
 {
 
  Error_Handler();
 
 }
 
 */
 
   
 
  if (HAL_ADC_Start_DMA(&hadc,
 
            (uint32_t*) &adcBuffer,
 
            4 //SIZE OF ADC MULTI CHANNEL
 
            ) != HAL_OK)
 
 {
 
  Error_Handler();
 
 }
 
  
 
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); //DMA-ADC begins 
 
 
 

  Thanks for read.

1 REPLY 1
KnarfB
Principal III

There is an app note "How to get the best ADC accuracy in STM32 microcontrollers" with some general tips and remarks.