cancel
Showing results for 
Search instead for 
Did you mean: 

ADC Reading Value

Peter Simpson
Associate II
Posted on June 21, 2018 at 03:47

Hi, 

      I am to use the ADC on a STM32L072 to read three channels , ADC_CHANNEL_5, VREFINT and TEMPSENSOR.

      I have set up the project in STM32CubeMX and select the three channels

     The code generated is below

static void MX_ADC_Init(void)

{

ADC_ChannelConfTypeDef sConfig;

/**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;

hadc.Init.Resolution = ADC_RESOLUTION_12B;

hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;

hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;

hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc.Init.ContinuousConvMode = DISABLE;

hadc.Init.DiscontinuousConvMode = DISABLE;

hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;

hadc.Init.DMAContinuousRequests = DISABLE;

hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;

hadc.Init.LowPowerAutoWait = DISABLE;

hadc.Init.LowPowerFrequencyMode = DISABLE;

hadc.Init.LowPowerAutoPowerOff = DISABLE;

if (HAL_ADC_Init(&hadc) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

/**Configure for the selected ADC regular channel to be converted.

*/

sConfig.Channel = ADC_CHANNEL_5;

sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;

if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

/**Configure for the selected ADC regular channel to be converted.

*/

sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;

if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

/**Configure for the selected ADC regular channel to be converted.

*/

sConfig.Channel = ADC_CHANNEL_VREFINT;

if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

}

uint32_t get_adc_value(void)

{

uint32_t ADCValue[4];

uint8_t loop = 0;

if (HAL_ADC_Start(&hadc) != HAL_OK)

{

/* Start Conversation Error */

// Error_Handler();

}

while(loop < 4)

{

if (HAL_ADC_PollForConversion(&hadc, 1000000) != HAL_OK)

{

/* End Of Conversion flag not set on time */

// Error_Handler();

ADCValue[0] = 0;

return(ADCValue[0]);

}

else

{

/* ADC conversion completed */

/*##-5- Get the converted value of regular channel ########################*/

ADCValue[loop++] = HAL_ADC_GetValue(&hadc);

}

}

HAL_ADC_Stop(&hadc);

return((ADCValue[0] + ADCValue[1] + ADCValue[2] + ADCValue[3])/4);

// return(ADCValue[0]);

}

int main(void)

{

/* USER CODE BEGIN 1 */

/* USER CODE END 1 */

/* MCU Configuration----------------------------------------------------------*/

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

/* USER CODE BEGIN Init */

/* USER CODE END Init */

/* Configure the system clock */

SystemClock_Config();

/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_ADC_Init();

/* Initialize interrupts */

MX_NVIC_Init();

/* USER CODE BEGIN 2 */

adc_reading = get_adc_value();

vdd = 3000 * (* VREFINT_CAL_ADDR ) / adc_reading ;

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

In the code during initialization , the three channels are configured using

HAL_ADC_ConfigChannel (....)

but there does not seem to be any way of selecting which of the three channels i read in the 

get_adc_value() function. 

Would anyone have any advice about how to select or tell which channel is being read when data is collected

Thank You

Regards

1 REPLY 1
T J
Lead
Posted on June 21, 2018 at 04:42

When you use the DMA circular buffer, the data values are always saved in the same location,

you then just wait for the complete interrupt to get all three values.

It is not recommended to process those values within the interrupt,

but to save the data and flags for processing in a foreground thread. ( more like an OS)

However, if you are quick < 60uS  then process it inside the interrupt.

it is not recommended to remain inside an interrupt beyond 20uS, but its ok of course, you have to manage your issues.