I need to read 15 channels ADC. However my MCU is specific named STM32F042K6T6. I decided to use an analog MUX to read every channel from just one pin. But, I didn't read accurately the datas by writing these codes:
for ( z = 0; z <= 15; z += 1 )
{
HAL_GPIO_WritePin(GPIOA, ADC_CH_SELECT0_Pin, ( z >> 0) & 0x01 ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, ADC_CH_SELECT1_Pin, ( z >> 1) & 0x01 ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, ADC_CH_SELECT2_Pin, ( z >> 2) & 0x01 ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, ADC_CH_SELECT3_Pin, ( z >> 3) & 0x01 ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
When I decrease the repetition count of for, namely for (z=0; z<=2; z++)
The results is OK. But I can not read all the channels with that. Because of this problem, I decided to use an adc interrupt. I have set all the settings like ADC resolution, Cycle, right alignment, NVIC e.t.c. with STMCUBEMX. These codes are here:
static void MX_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
And I know that when the configurations are OK, I need to Start ADC INT with that code:
HAL_ADC_Start_IT(&hadc);
I have inserted the code within main function above from while.
And I know that after every reading cycle, our program must jump to that function:
void HAL_ADC_ConvtCpltCallback(ADC_HandleTypeDef* hadc)
{
Temporary_ADC_Value[0] = HAL_ADC_GetValue(hadc);
}
When I try to read adc value from Temporary_ADC_Value[0], I have not experienced a appropriate value. What may be the problem about issue? Is there any point that I forget? That issue is important for me. Thanks in advance.
for
loop will go, are you allowing the ADC to complete a sample before selecting another channel to read? Usually after selecting the channel you will have to wait for a conversion to complete before changing the channel. I would allow 2 conversions in case the conversion started in the middle of your mux switch. There is also a non-zero time for the mux to select a new channel and output it. \$\endgroup\$ADC_CH_SELECT_EN
to low to enable the output on the mux. \$\endgroup\$