STM32L151 ADC in scan mode
Hi,
I'm trying to use the ADC1 of the STM32L151CBT6A in scan mode for 14 channels (with interrupt) .
Depending on ADC clock and SamplingTime configuration I got only a channel on 2. If I put sampling time lower than 96 cylces (for prescaler 4) I have :
adcValue[0]=Channel 0
adcValue[1]=Channel 2
adcValue[2]=Channel 4
adcValue[3]=Channel 6
.
.
.
Instead of :
adcValue[0]=Channel 0
adcValue[1]=Channel 1
adcValue[2]=Channel 2
adcValue[3]=Channel 3
.
.
.
If I put 96 cylces or higher everything OK.
I don't have any overun because I configure CR2->DELS to ADC_AUTOWAIT_UNTIL_DATA_READ and I also check that ErrorCallback is never call.
I use CubeMX to generate base code (STM32 HAL lib), here is ADC init :
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.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE;
hadc.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;
hadc.Init.ChannelsBank = ADC_CHANNELS_BANK_A;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.NbrOfConversion = 14;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
MODIFY_REG(ADC1->CR2,ADC_CR2_DELS_Msk,ADC_AUTOWAIT_UNTIL_DATA_READ);
sConfig.SamplingTime = ADC_SAMPLETIME_96CYCLES;
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 2;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 3;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_18;
sConfig.Rank = 4;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = 5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = 6;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = 7;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = 8;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_19;
sConfig.Rank = 9;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK){
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_20;
sConfig.Rank = 10;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK){
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_9;
sConfig.Rank = 11;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK){
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_21;
sConfig.Rank = 12;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK){
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = 13;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = 14;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK){
Error_Handler();
}
}Here is interrupt management :
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
adcValue[adcChannel]=HAL_ADC_GetValue(hadc);
if(adcChannel == (NUMBER_OF_ADC_CHANNEL-1)){
adcChannel = 0;
adcConvCplt = true;
}
else{
adcChannel++;
}
}Does any one have an idea ?
Best regards
