cancel
Showing results for 
Search instead for 
Did you mean: 

How to use two ADCs in different modes and interrupt callbacks?

rakib2023
Associate III

I am using NUCLEO-F756ZG. I intend to use two of the ADCs but in different conditions. ADC1 is configured for DMA and triggered by TIM1 to run at high speed (1 Msps), ADC2 is configured for interrupt mode and triggered by TIM8 to run at low speed (1~20 sps).I have two questions.

 

1. I want to use different callbacks for the two ADCs. I know about HAL_ADC_RegisterCallback function. Should I be using them right after MX_ADCx_Init call or modify the MX_ADCx_Init to register the callbacks during init?

 

2. Looking at CubeMX generated IRQHandler, and since ADC interrupt is global for all 3 ADCs, it seems that interrupt will be called after each sampling of ADC1 too. How should I modify it so that ADC1 doesn't call interrupt and only ADC2 does. I only need to process ADC1 data after full DMA transfer completes. Should I leave an empty callback for ADC1 and move the intended routine to DMA_xferCpltCallback?

 

Thanks for your time. Due to situations, I am stuck with using HAL and can't write up everything from scratch. I appreciate all help.

1 ACCEPTED SOLUTION

Accepted Solutions
Imen.D
ST Employee

Hello @rakib2023 ,

  1. Both ADCs are initialized using the MX_ADCx_Init functions. The HAL_ADC_RegisterCallback function is used to register the conversion complete callbacks for each ADC. This is done immediately after the ADC initialization. The ADC1_ConvCpltCallback and ADC2_ConvCpltCallback functions are defined to handle the conversion complete events for ADC1 and ADC2, respectively.

  2. You can modify the generated IRQHandler and use an empty callback for ADC1. You can then move the intended routine to the DMA transfer complete callback. This ensures that the ADC interrupt is only processed for ADC2, while ADC1 data is handled after the DMA transfer completes. 

    So, in this case, you can modify the ADC_IRQHandler function to check which ADC triggered the interrupt. If the interrupt is for ADC2, the HAL_ADC_IRQHandler function is called to handle the interrupt.

    After that, register an empty callback for ADC1 to ensure that no processing is done during the ADC interrupt.

    Then, using the HAL_DMA_ConvCpltCallback function to handle the DMA transfer complete event for ADC1.
    By following these steps, you can ensure that the ADC interrupt is only processed for ADC2, while ADC1 data is handled after the DMA transfer completes.
 
When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen

View solution in original post

1 REPLY 1
Imen.D
ST Employee

Hello @rakib2023 ,

  1. Both ADCs are initialized using the MX_ADCx_Init functions. The HAL_ADC_RegisterCallback function is used to register the conversion complete callbacks for each ADC. This is done immediately after the ADC initialization. The ADC1_ConvCpltCallback and ADC2_ConvCpltCallback functions are defined to handle the conversion complete events for ADC1 and ADC2, respectively.

  2. You can modify the generated IRQHandler and use an empty callback for ADC1. You can then move the intended routine to the DMA transfer complete callback. This ensures that the ADC interrupt is only processed for ADC2, while ADC1 data is handled after the DMA transfer completes. 

    So, in this case, you can modify the ADC_IRQHandler function to check which ADC triggered the interrupt. If the interrupt is for ADC2, the HAL_ADC_IRQHandler function is called to handle the interrupt.

    After that, register an empty callback for ADC1 to ensure that no processing is done during the ADC interrupt.

    Then, using the HAL_DMA_ConvCpltCallback function to handle the DMA transfer complete event for ADC1.
    By following these steps, you can ensure that the ADC interrupt is only processed for ADC2, while ADC1 data is handled after the DMA transfer completes.
 
When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen