2025-09-29 12:55 AM
Hello,
I have two channels on ADC1 and I want to trigger a s ample separately, every two seconds from first channel and every 10th second from second channel. I am using interrupts so after the adc trigger I get an interrupt when conversion is done. But it seems i only get a sample or read it from the first channel. I am new to stm32 microcontroller so i am not sure what can be wrong. I am configering everything and using an interrupt handler for reading the ready sample. I get the interrupt after each trigger but it seems i am getting the value from the first channel.
__HAL_RCC_VREF_CLK_ENABLE(); // enable the internal voltage reference
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.GainCompensation = 0;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
hadc1.Init.OversamplingMode = DISABLE;
ADC_RegisterHandle(&hadc1);
sConfig.SamplingTime = ADC_SAMPLETIME_391CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.Channel = ADC_CHANNEL_5;
sConfig.Rank = ADC_REGULAR_RANK_1;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_REGULAR_RANK_2;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
__HAL_ADC_CLEAR_FLAG(&adc1, ADC_FLAG_EOC);
__HAL_ADC_CLEAR_FLAG(&adc1, ADC_FLAG_OVR);
__HAL_ADC_CLEAR_FLAG(&adc1, ADC_FLAG_EOS);
HAL_NVIC_SetPriority(ADC1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_IRQn);
__HAL_ADC_ENABLE_IT(&adc1, ADC_IT_EOC);
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
Public void ADC_RegisterHandle(ADC_HandleTypeDef *handle)
{
hadc1 = handle;
}
This is my interrupt handler:
Public void ADC1_IRQHandler(void)
{
if (__HAL_ADC_GET_FLAG(adc1, ADC_FLAG_EOS)){ //test code to check set flags
if (NULL != adcValueCB) {
// just for test to see if interrupt is received
}
}
if (__HAL_ADC_GET_FLAG(adc1, ADC_FLAG_EOC)){
if (NULL != adcValueCB) {
// just for test to see if interrupt is received
}
}
if (__HAL_ADC_GET_FLAG(adc1, ADC_FLAG_OVR)){
if (NULL != adcValueCB) {
// just for test to see if interrupt is received
}
}
HAL_ADC_IRQHandler(adc1); //hal library from stm32
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if (hadc->Instance == ADC1) {
uint32_t ch1 = HAL_ADC_GetValue(hadc); // here I always get the value from first sampled channel, channel 5
adcValueCB(&ch1); // return value to rest of the program
__HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR); // clear flags that are not cleared by getting the value
__HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOS);
}
}
In the code loop I trigger the conversion:
Get the number of channel I want a sample from, sent from the rest of the program at different intervals
sConfig.Channel = inputChannel;
sConfig.Rank = GetChannelRank(inputChannel);
HAL_ADC_ConfigChannel(&adc1, &sConfig);
SysCtlDelay(10); // delay of 10 ms after changing channels to stabilize
HAL_ADC_Start_IT(&hadc1);
Is there anything I am missing?
Best regards,
Gergana