Skip to main content
Explorer
August 7, 2024
Solved

STM32L071 and ADC channel 5 and 6 rank

Hello, I have configure ADC to use channel 5 and 6 but I am not understanding what I am doing wrong to get readings from the two channels. 

Here is my code:

void adcConvertionFinish(ADC_HandleTypeDef* handle);

static ADC_HandleTypeDef g_adc;
static const uint32_t g_shutter_pin = GPIO_PIN_5;
static const uint32_t g_window_pin = GPIO_PIN_6;
static adcPowerMeterConvertionFinishHandler g_adc_conversion_finish_handler = NULL;
static void* g_adc_convertion_finish_obj = NULL;

bool adcPowerMeterInit()
{
 __HAL_RCC_ADC1_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();

 GPIO_InitTypeDef init_struct = {0};
 init_struct.Pin = g_shutter_pin | g_window_pin;
 init_struct.Mode = GPIO_MODE_ANALOG;
 init_struct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &init_struct);

 ADC_ChannelConfTypeDef config = {0};
 g_adc.Instance = ADC1;
 g_adc.Init.OversamplingMode = DISABLE;
 g_adc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
 g_adc.Init.Resolution = ADC_RESOLUTION_12B;
 g_adc.Init.SamplingTime = ADC_SAMPLETIME_39CYCLES_5;
 g_adc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
 g_adc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
 g_adc.Init.ContinuousConvMode = ENABLE;
 g_adc.Init.DiscontinuousConvMode = DISABLE;
 g_adc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
 // g_adc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T6_TRGO;
 g_adc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
 g_adc.Init.DMAContinuousRequests = DISABLE;
 g_adc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
 g_adc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
 g_adc.Init.LowPowerAutoWait = DISABLE;
 g_adc.Init.LowPowerFrequencyMode = DISABLE;
 g_adc.Init.LowPowerAutoPowerOff = DISABLE;

 if(HAL_ADC_Init(&g_adc) != HAL_OK)
 return false;

 config.Channel = ADC_CHANNEL_5;
 config.Rank = ADC_RANK_CHANNEL_NUMBER;

 if(HAL_ADC_ConfigChannel(&g_adc, &config) != HAL_OK)
 return false;

 config.Channel = ADC_CHANNEL_6;
 if(HAL_ADC_ConfigChannel(&g_adc, &config) != HAL_OK)
 return false;

 if(HAL_ADC_RegisterCallback(&g_adc, HAL_ADC_CONVERSION_COMPLETE_CB_ID, adcConvertionFinish)
 != HAL_OK)
 return false;

 HAL_NVIC_SetPriority(ADC1_COMP_IRQn, g_adc_powermonitor_preempt, g_adc_powermonitor_sub);
 HAL_NVIC_EnableIRQ(ADC1_COMP_IRQn);
 return true;
}
void adcPOwerMeterDeInit()
{
 __HAL_RCC_ADC1_CLK_DISABLE();
 HAL_GPIO_DeInit(GPIOA, g_shutter_pin | g_window_pin);
 HAL_NVIC_DisableIRQ(ADC1_COMP_IRQn);
}

void adcConvertionFinish(ADC_HandleTypeDef* handle)
{
 uint32_t val2 = 0, val1 = 0;

 val1 = HAL_ADC_GetValue(&g_adc);
 val2 = HAL_ADC_GetValue(&g_adc);

 if(g_adc_conversion_finish_handler && handle->Instance == g_adc.Instance)
 g_adc_conversion_finish_handler(g_adc_convertion_finish_obj, val1, val2);
}

void adcPowerMeterSetConvertionFinishHandler(adcPowerMeterConvertionFinishHandler handler, void* obj)
{
 g_adc_conversion_finish_handler = handler;
 g_adc_convertion_finish_obj = obj;
}

void adcPowerMeterStart()
{
 HAL_ADC_Start_IT(&g_adc);
}

void adcPowerMeterStop()
{
 HAL_ADC_Stop_IT(&g_adc);
}

// HAL Functions
void ADC1_COMP_IRQHandler(void)
{
 HAL_ADC_IRQHandler(&g_adc);
}

At adcConvertionFinish function, I am getting allways the value of the channel 5 (on both variables val1 val2). I am following a example of using rank's to get values from two channels that I found on web, but it is not working for me.

My goal is to start a convertion (get convertion for channel 5 and channel 6), then when it is finish, get the values. 

What I am doing wrong?

 

Thank you for you help in advance

This topic has been closed for replies.
TDK
TDKBest answer
August 7, 2024

Use DMA to convert more than one channel at a time.

 

> val1 = HAL_ADC_GetValue(&g_adc);
> val2 = HAL_ADC_GetValue(&g_adc);

There is no FIFO in the ADC. Such a scheme cannot work. You must read out a channel before the next one is converted or you will get an overrun.

 

Here is an example of using ADC on multiple channels:

STM32CubeL0/Projects/NUCLEO-L053R8/Examples/ADC/ADC_Sequencer/Src/main.c at a91b71702355c483e72868edd3fb620e4278e017 · STMicroelectronics/STM32CubeL0 (github.com)

"If you feel a post has answered your question, please click ""Accept as Solution""."

1 reply

TDK
TDKBest answer
August 7, 2024

Use DMA to convert more than one channel at a time.

 

> val1 = HAL_ADC_GetValue(&g_adc);
> val2 = HAL_ADC_GetValue(&g_adc);

There is no FIFO in the ADC. Such a scheme cannot work. You must read out a channel before the next one is converted or you will get an overrun.

 

Here is an example of using ADC on multiple channels:

STM32CubeL0/Projects/NUCLEO-L053R8/Examples/ADC/ADC_Sequencer/Src/main.c at a91b71702355c483e72868edd3fb620e4278e017 · STMicroelectronics/STM32CubeL0 (github.com)

"If you feel a post has answered your question, please click ""Accept as Solution""."