Skip to main content
DU2
Associate II
October 7, 2020
Question

L031K6 : ADC value is not similar as real value

  • October 7, 2020
  • 1 reply
  • 667 views

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.

This topic has been closed for replies.

1 reply

KnarfB
Super User
October 7, 2020

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