2023-02-14 07:39 AM
Can anybody point me to example of two or more ADC channels polling?
I'm trying to measure two channels of one ADC but it looks like it reads one channel twice
Initialization:
static void MX_ADC1_Init(void)
{
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; // scan all channels?
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 2;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; //<<<<
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_2;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
Reading;
void ADC_read2meas(ADC_HandleTypeDef *hADC_NAC, uint16_t *p1, uint16_t *p2)
{
HAL_StatusTypeDef st = HAL_ADC_Start(hADC_NAC);
if (st != HAL_OK) {
Error_Handler();
}
st = HAL_ADC_PollForConversion(hADC_NAC, 3 /*ms*/);
if (st != HAL_OK) {
Error_Handler();
}
//1
uint32_t v = HAL_ADC_GetValue(hADC_NAC);
if (v & 0xFFFFF000) {
Error_Handler(); // does not fit in 12 bits
}
*p1 = v & 0xFFF;
v = HAL_ADC_GetValue(hADC_NAC);
if (v & 0xFFFFF000) {
Error_Handler(); // does not fit in 12 bits
}
*p2 = v & 0xFFF;
}
Need to call start twice or call HAL_ADC_PollForConversion twice?
Solved! Go to Solution.
2023-02-15 06:51 AM
2023-02-15 01:04 PM
Thank you @KnarfB Sampling time in your project is much longer than mine, this can explain why it works with polling.
2023-02-15 01:46 PM
Ohh, that really makes a difference. Have reduced that time to the minimum and it stopped working. Saw the overrun flag set in ADC ISR.
As a remedy, I enabled Discontinuous Conversion Mode (1), and moved HAL_ADC_Start into the inner loop. That works for me.
hth
KnarfB
2023-10-15 04:44 AM
In the Configuration part , don't we need two instances of sConfig for 2 different channel or only one instance will work no matter the number of channel?
2023-10-15 06:38 AM
@Tushar_4 The sConfig struct can be reused after HAL_ADC_ConfigChannel call. One instance will do. But this is not obvious in C code, you're right.