2021-01-03 05:34 AM
Hi all, as mentioned in the title i have an issue with the ADC configured to sampling 4 channels with different rank.
I want to collect the sample in one array ( array uint16_t values[4] ) in the same order for each conversion done. The data in the array are correct, but the position in the array of the data change continuosly, like a swapping. Can someone help me?
I don't want fow now use DMA, i want to learn to manage properly this basic things before.
Thank you all.
This is my code:
/* ADC Config */
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 4;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_12;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
I start the ADC with "HAL_ADC_Start_IT(&hadc1);" command and the interrupt functions contains this code :
/* ADC Interrupt Get values */
void ADC_IRQHandler(void)
{
values[i] = ADC1->DR; // already try with values[i]= HAL_ADC_GetValue(&hadc1);
i=i+1;
if(i==4)
{
i=0;
}
HAL_ADC_IRQHandler(&hadc1);
}
values is array of 4 elements uint16_t
2021-01-03 07:28 AM
The ADC completes 4 conversions in a very short duration and your code is not able to keep up with that.
You can look into discontinuous mode if you want to convert only 1 channel per trigger.
2021-01-03 07:41 AM
The ADC has only one register to store conversion results. NbrOfConversion greater than 1 works only with DMA. For single conversions, configure the numbers.Config.Channel RANK_1 with the next channel for the next conversion.
After you achieve your understanding, look at ST's L4 example Nucleo-L4P5ZG ADC_Sequencer for ADC DMA guidance.
Cheers, Hal