STM32L071 reading multiple ADC channels
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-04-15 3:36 AM
Hello. We chose STM32L071 CPU without realising that it does not have Scan conversion mode for multiple ADC channels.
Can someone confirm if it is possible to read multiple ADC channels using this CPU?
Please suggest what is the most convenient way to do this.
- Labels:
-
ADC
-
STM32CubeMX
-
STM32L0 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-04-15 5:14 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-04-16 2:00 AM
Opened the reference manual and saw that the ADC can scan multiple channels. Where is the problem?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-04-18 11:08 PM
Can you send me a link? The L071 does not have scan conversion mode which is a mode that is usually used when read multiple channels simultaneously
UPDATE:
I have found where they mention scan mode in the documentation of the STM32L071:
However, it wont let me configure this in the cubeMX
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-04-19 12:58 AM
The following is a schematic:
And the cubemx confguration:
I have tried to read multiple channels with the following code: This is just a snipper from a code, I am not inclugind HAL init functions that are irrelevant
void select_adc_channel(int channel)
{
ADC_ChannelConfTypeDef sConfig = {0};
switch (channel)
{
case 0:
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
break;
case 1:
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
break;
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
case 2:
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
break;
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
case 3:
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = 1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
break;
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
default:
break;
}
}
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
for(int i = 0; i< Max_Channels; i++)
{
select_adc_channel(i);
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
adcValue[i] = HAL_ADC_GetValue(&hadc);
printf("adc value[%i]=%u \n",i,adcValue[i]);
}
printf("\n");
HAL_Delay(1000);
}
/* USER CODE END 3 */
}
The above does not work. When I short the adc0 pin to ground, all other adc readings change as well:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-04-19 12:59 AM
Wherever I look, everybody is using the following parameter when dealing with multiple adc channels:
hadc1.Init.ScanConvMode = ENABLE;
This does not seem to be available for STM32L071. So I am hoping that there is another way
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-04-19 1:28 AM
In the cubemx, I should be able to configure my channels as it shown in this example :
However, in my cubemx, I have no such options:
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-04-19 11:58 AM
Maybe better is read and understand HAL functions , for example part from HAL_ADC_ConfigChannel(
if (sConfig->Rank != ADC_RANK_NONE)
{
/* Enable selected channels */
hadc->Instance->CHSELR |= (uint32_t)(sConfig->Channel & ADC_CHANNEL_MASK);
/* Management of internal measurement channels: Vlcd (STM32L0x3xx only)/VrefInt/TempSensor */
/* internal measurement paths enable: If internal channel selected, enable */
/* dedicated internal buffers and path. */
as you can see here is |= then every call this add new channel, but dont remove prev. then your select func cant work. Too in HAL source is explain howto use ranks usw.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-04-19 10:21 PM
Thanks for clarifying. But I still cannot fully make sense out of it. What you said is only true when ADC_RANK_NONE is selected. In my case, all channels were assigned RANK 1
hadc->Instance->CHSELR &= ~((uint32_t)(sConfig->Channel & ADC_CHANNEL_MASK));
.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-04-20 2:08 AM
/** @defgroup ADC_rank ADC rank
* @{
*/
#define ADC_RANK_CHANNEL_NUMBER (0x00001000U) /*!< Enable the rank of the selected channels. Number of ranks in the sequence is defined by number of channels enabled, rank of each channel is defined by channel number (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...) */
#define ADC_RANK_NONE (0x00001001U) /*!< Disable the selected rank (selected channel) from sequencer */
/**
* @}
*/
and you missread in my example code was ! NONE
