cancel
Showing results for 
Search instead for 
Did you mean: 

Irregular adc conversions triggered / synchronized by timer

lserrnt
Associate II

Hi there!
I'm working with a nucleo144-STM32F767zi and facing a problem with irregular ADC conversions (HAL_ADC_Start_IT) which are triggered by a eg. 50 kHz timer update event (every 20 us TIM1 fires an update event)

lserrnt_1-1693572140484.png

ADC Clock prescaler seems to be PCLK2 / 4 = 96 MHz / 4 = 24 MHz according to my clock configuration

lserrnt_2-1693573420554.png

So I expect the quickest ADC conversion rate to be 24 MHz / (12+3 cycles) = 1.6 MHz -> 0,625 us which is way below my desired timer triggered conversion of 20 us.

However my adc readings are irregular every 1 millisecond for one reading. In the image below I have triggered a output pin which I read via an oscilloscope.

 

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
 adc_val = HAL_ADC_GetValue(&hadc1);
 GPIOA -> ODR ^= GPIO_PIN_3;
}

 

 

I don't do anything with the adc value yet. When I look at the signal, I have every 1 ms this longer timing of up 7-10 us longer for one reading (the conversion takes 7-10us more time). This limit my maximum frequency to 50 kHz, at 100 kHz I have missing values! If I toogle this pin without active adc, I get a perfectly regular 50 kHz oscillation triggered by timer period elapsed callback.

lserrnt_0-1693572061169.png

I have initialzed USB and huart in a non blocking mode and I'm not sending or receiving anything during adc reading. I am also not using the 1 ms systick handler in any way. So I dont understand, why I get these glitches every 1 millisecond. I am not using any delays.
Does anyone know why this may occur ? I appreciate any help here 🙂 

Thank you in advance 🙂

 

It would also be okay to just find a way around this maybe via DMA? But my readings must be perfectly at 100 kHz or 50 kHz spacing, so I must be able to rely on the spacing between my values which is why I implemented this with single read and with the conversion complete callback

1 ACCEPTED SOLUTION

Accepted Solutions

USB SOF interrupt may be enabled.

Set higher priority to ADC interrupt.

JW

View solution in original post

6 REPLIES 6

USB SOF interrupt may be enabled.

Set higher priority to ADC interrupt.

JW

TDK
Guru

Are you actually disabling the SysTick interrupt? It will still be running and interrupting at 1kHz even if you're not actively calling HAL_GetTick or similar.

If ADC is triggered from a timer, the sample frequency will be uniform even if you callback has jitter to it.

Yes, DMA could be used to avoid the problem of the interrupt not being called often enough. Interrupts at 100 kHz are going to be at the upper end of what is possible with HAL.

If you feel a post has answered your question, please click "Accept as Solution".

this might be the case, I don't have my laptop with me. I can check on this later on today. sry for late reply, I thought I would get email notifications 😅

Thank you 🙂

I have not disabled the systick interrupt. I didn't know this with the limited interrupt frequency.

 

@TDK so you're saying that in reality the ADC value was sampled perfectly in time, and that just the callback was delayed in time? So my measurements were still valid?

So I might be doing it with DMA then. I also have a timer running in encoder mode and I think I have there also interrupts enabled. I'll check on this later on today. thank you ! 🙏

I have not disabled the systick interrupt.

That explains the 1 kHz disruption.

> so you're saying that in reality the ADC value was sampled perfectly in time, and that just the callback was delayed in time? So my measurements were still valid?

Yes.

Glad you got it working.

If you feel a post has answered your question, please click "Accept as Solution".

It wasn't the systick interrupt. This still led to irregular adc readings every 1 ms. After setting USB On The Go FS global interrupt Preemption Priority to 1 the irregular readings were gone. Thanks a lot!

lserrnt_0-1693821091652.png