Skip to main content
Associate II
October 16, 2023
Question

trigger DMA with ADC1 and ADC2 using different timer

  • October 16, 2023
  • 3 replies
  • 4488 views

Hi, 

I want to have 2 ADC interrupts with DMA. ADC1 is triggered using TIM1 at 4kHz, while ADC2 is triggered using TIM4 at 74kHz. Two different timers are used for different ADC to have different sampling time. The ADC2 is set as Medium priority while the ADC1 is at low priority.

Questions are as below:

1. If more lines are added in "hadc==&hadc2" then it changes the ADC2 interrupt frequency from 74kHz to lower values. I did not understand why ?

2. How to confirm the conversion + sampling time for each ADCs ?

3. There is another timer interrupt triggered at 4 kHz, how to understand the priorities of all 3 Interrupts (ADC1(TIM2), ADC2(TIM4), TIM1) with respect to each other ?

Here is the code snippet. 

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if(hadc==&hadc1)

{

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);

//2.5 cycles for sampling time

VA=ADC1_buffer1[0]; 
VB=ADC1_buffer1[1]; 
VC=ADC1_buffer1[2]; 
 
IA=ADC1_buffer1[3];
IB=ADC1_buffer1[4];
IC=ADC1_buffer1[5];
 
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
 
Please help me !

}

if(hadc==&hadc1)

{

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);

// 12.5 cycles for sampling time

 X=ADC_buffer1[0];
 Y=ADC_buffer1[1];
 z=ADC_buffer1[2];
 
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);

}

}

This topic has been closed for replies.

3 replies

Tesla DeLorean
Guru
October 16, 2023

Presentation here is very lacking. Can't see the code related to "hadc==&hadc2"

Post / attach something that is at least functionally complete / compilable.

Identify parts involved.

If you toggle a GPIO in the DMA callback a scope can check frequency of HT/TC interrupts.

Output triggers to additional channels you can get scope pins too.

Priorities shouldn't be a significant issue unless you're doing excessive amount of things in the handlers or call-backs, and/or blocking. Could perhaps explain why frequencies are off, but again code really not showing that.

 

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
VidhiPaAuthor
Associate II
October 16, 2023

Hi Tesla, 

Thank you for the response. Please find the corrected code asbelow

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if(hadc==&hadc1)

{

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);

//2.5 cycles for sampling time

VA=ADC1_buffer1[0]; 
VB=ADC1_buffer1[1]; 
VC=ADC1_buffer1[2]; 
 
IA=ADC1_buffer1[3];
IB=ADC1_buffer1[4];
IC=ADC1_buffer1[5];
 
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
 
Please help me !

}

if(hadc==&hadc2)

{

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);

// 12.5 cycles for sampling time

 X=ADC_buffer1[0];
 Y=ADC_buffer1[1];
 z=ADC_buffer1[2];
 
/*I cant show the whole code here, but here there are 2 control loops running, which has filtering of the measurement signals coming from ADC, PI controllers, and PWM compare register update. */
 
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);

}

}

I am using Nucleo-G431RB evaluation board. 


@Tesla DeLorean wrote:

If you toggle a GPIO in the DMA callback a scope can check frequency of HT/TC interrupts. 


I am using scope to find out the frequency. 

The other TIM1 interrupt also has a motor control code, running at 4 kHz.

 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
 
if (htim==&htim1)
{
/*
filtering the measured signal,
calculate the angle and amplitude, 
PI controller, 
saturators using if, else, 
update the compare registers of PWM
*/
}
}
 
TDK
Super User
October 16, 2023

> 1. If more lines are added in "hadc==&hadc2" then it changes the ADC2 interrupt frequency from 74kHz to lower values. I did not understand why ?

You're interrupting too much and the CPU can't keep up. Lower the interrupt rate by increasing buffers and/or using DMA.

> 2. How to confirm the conversion + sampling time for each ADCs ?

The reference manual information is correct. If you want to verify, do 5000 conversions and measure the duration to do all of them. You cannot usefully measure the duration of a single ADC conversion.

> 3. There is another timer interrupt triggered at 4 kHz, how to understand the priorities of all 3 Interrupts (ADC1(TIM2), ADC2(TIM4), TIM1) with respect to each other ?

Interrupts are independent. Highest priority wins. Typically they can pre-empt each other but it can be configured differently.

"If you feel a post has answered your question, please click ""Accept as Solution""."
VidhiPaAuthor
Associate II
October 16, 2023

@TDK wrote:

> 1. If more lines are added in "hadc==&hadc2" then it changes the ADC2 interrupt frequency from 74kHz to lower values. I did not understand why ?

You're interrupting too much and the CPU can't keep up. Lower the interrupt rate by increasing buffers and/or using DMA. 

I am using buffers to reduce the control loops to 20kHz and another at 10kHz,

What is the effective way of obtaining ?

  1. Ia, Ib, Ic, Va, Vb, Vc measurement at 4kHz,
  2. one control loop running at 4 kHz, 
  3. Vdc, Vac, IL measurements at 74kHz 
  4. and 2 control loops running at 20 kHz, and 10kHz.

I am using 

ADC1(TIM2) interrupt at 4kHz for the measurement,

ADC2(TIM4) for 2 control loops running at 20 and 10 kHz within TIM4 interrupt running at 74 kHz,

TIM1 interrupt for PWM and control loop running at 4kHz. 

Please find attached screenshot of the ADC1, ADC2 and NVIC settings. 


@TDK wrote:

Interrupts are independent. Highest priority wins. Typically they can pre-empt each other but it can be configured differently.


where can i set the priority of timer interrupt with respect to ADC interrupts ?

 

Thanking you!

TDK
Super User
October 16, 2023

I would do the 74 kHz samples on ADC1, and the 20, 10, and 4 kHz samples on ADC2. Use large enough buffers so you only have to process data every few ms or tens of ms. Use decimation or averaging to get 4/10 kHz out of 20kHz sampling.

Interrupt priority is the "preemption priority" column in your screenshot. Numerically lower values are higher priority, 0 is the highest priority, 15 is the lowest priority.

"If you feel a post has answered your question, please click ""Accept as Solution""."
TDK
Super User
October 17, 2023

I laid out the guidelines I would use in a previous post and mentioned the issues with interrupts happening at a high frequency. Can't write the actual code for you. I don't think I have the capacity to help much more. Perhaps there is a coworker or someone else more invested in the project.

I suggest working on one thing at a time and optimizing it to use a small amount of computational resources. Interrupts should all be independent so you can combine them at the end.

"If you feel a post has answered your question, please click ""Accept as Solution""."
VidhiPaAuthor
Associate II
October 18, 2023

Of course, I would not even ask you to do that !

I tried to explain it in detail to understand better what you suggested "to reduce the sampling rate and using large buffers". Sampling rate I cannot change, since that is the customer requirement. I am already using buffers to slow down my loops further. thank you for the guideline.