2024-08-07 03:46 AM
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
Solved! Go to Solution.
2024-08-07 04:46 AM
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:
2024-08-07 04:46 AM
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: