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.

hadc1.Instance = ADC1;
{
Error_Handler();
}

/**Configure Regular Channel
*/
sConfig.Rank = 1;
{
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)
{

sConfig.Channel = channel;
sConfig.Rank = 1;

/* Start conversion with interrupt*/
{
}

return err_code;
}


And finally my callback:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
{
}
else
{
}
}


Did I forget something in the callback?

• Are you clearing the interrupt anywhere? – Eugene Sh. Jun 16 '16 at 14:01
• @EugeneSh.: No. I think that in continuous mode, the interrupt cleaning is not needed. Do I clean IT? Thanks – Federico Jun 16 '16 at 14:03
• Hey, now I see. You are not setting the callback properly at all. But you are just manually calling your HAL_ADC_ConvCpltCallback so you see it is called. – Eugene Sh. Jun 16 '16 at 14:05
• Ah, wait. I see. STM code has a weak declaration of a function of the same name, so it is set as a callback automatically? – Eugene Sh. Jun 16 '16 at 14:09
• Again, I don't have time to go deeply in a research here, but you might want to take a look here – Eugene Sh. Jun 16 '16 at 14:23

You forgot to enabled the ADC interrupts, which can be done something like this:

HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);


The next thing with HAL's interrupt handling is that there are two weak function declaration.

1. for void ADC_IRQHandler()
2. for 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 the HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc), parameter is your ADC's handler (ADC_HandleTypeDef).

void ADC_IRQHandler()
{
}


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 the void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc). As it also has a weak declaration, so you have to implement the function.

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
{
// Do stuff
}

//{
//
//}
}


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.

/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32f4xx.s).                    */
/******************************************************************************/

/**
*/
{
/* USER CODE BEGIN ADC_IRQn 0 */

/* USER CODE END ADC_IRQn 0 */