I'm facing with a problem regarding continuous acquisition of ADC channel in STM32F103.
I use the interrupt at the end of conversion to call a callback function to store the acquired value.
The problem regards the callback that is called only the first time.
I configured my project using STM32CubeMx for continuous acquisition and interrupt generation.
This is the ADC configuration:
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/**Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
This is my acquisition function:
ea_ADC_Err_Code_t ea_ADC_n_data_read(Adc_Channel_t channel, adc_eoc_callback adc_cb)
{
ea_ADC_Err_Code_t err_code = ADC_ERR;
ADC_ChannelConfTypeDef sConfig;
adc_read_value = 0;
adc_eoc_cb = adc_cb;
n_adc_acquisition = ADC_MAX_CONS_ACQ;
/* Deinit ADC */
//while(HAL_ADC_DeInit(&adc_handler) != HAL_OK);
/* Initialize ADC */
//HAL_ADC_Init(&adc_handler);
/* Configure ADC Channel */
sConfig.Channel = channel;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
HAL_ADC_ConfigChannel(&adc_handler, &sConfig);
/* Set ADC callback */
HAL_ADC_ConvCpltCallback(&adc_handler);
/* ADC Calibration */
//HAL_ADCEx_Calibration_Start(&adc_handler);
/* Start conversion with interrupt*/
if (HAL_ADC_Start_IT(&adc_handler) == HAL_OK)
{
err_code = ADC_OK;
}
return err_code;
}
And finally my callback:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if (n_adc_acquisition)
{
adc_read_value += HAL_ADC_GetValue(&adc_handler);
n_adc_acquisition--;
edi_Print_L1("ADC Callback %d\n", n_adc_acquisition);
}
else
{
HAL_ADC_Stop_IT(&adc_handler);
adc_read_value = adc_read_value >> ADC_DIVIDE_BY_EIGTH;
adc_eoc_cb(adc_read_value);
}
}
Did I forget something in the callback?
Best Answer
You forgot to enabled the ADC interrupts, which can be done something like this:
The next thing with HAL's interrupt handling is that there are two weak function declaration.
void ADC_IRQHandler()
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
You have to implement the
ADC_IRQHandler()
first, this will be called when an interrupt is generated by the ADC. Inside this function you have to call theHAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
, parameter is your ADC's handler (ADC_HandleTypeDef
).Now,
HAL_ADC_IRQHandler()
will check every kind of error for you (you can check it in its implementation) and if everything is fine, it will call thevoid HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
. As it also has a weak declaration, so you have to implement the function.In STM32CubeMX, in the ADC1 Configuration window, there is tab called NVIC Settings. Here you can enable the global interrupts for ADC1 and ADC2, and if you do so, then STM32Cube will implements the
void ADC_IRQHandler(void)
in the stm32f1xx_it.c file.Also it's just a brief summary, so I suggest to read through the tutorial, @Eugene Sh showed you.