cancel
Showing results for 
Search instead for 
Did you mean: 

Output of interrupt routine inconsistent between different bits?

MDrac.1
Associate III

Hi,

I'm having an issue which I can't seem to resolve:

I'm trying to change the output value of Pin9 (Port C) through an interrupt routine (TIM3).

If I put a simple XOR statement for this pin in the interrupt routine it works as expected.

However if I try to load in values from an array the output starts to become inconsistent. This is best seen in the attached screenshots from the oscilloscope.

I have checked in debug mode how many cycles there are between writes to the pin which is pretty consistent for both (40 for xor, 70 for array load). Why is there then a difference between the length of the two 1's (see screenshot array-output).

Code: https://github.com/maksimdrachov/yada-brussels

1 ACCEPTED SOLUTION

Accepted Solutions

Which STM32?

Your interrupt is re-entered twice per timer overflow, due to late flag clear.

Plus what KnarfB said above. MHz interrupts are foolish except in very special cases, and precision timing in 32-bitters is to be achieved using hardware. I wouldn't DMA into GPIO's output register (see below); I would DMA into timer's registers, probably using preloaded CCRx. Or, even better, I would use what's intended for serialization: SPI, I2S.

Plus never change ODR in interrupt, you'll risk atomicity issues. Use BSRR instead.

JW

View solution in original post

3 REPLIES 3
KnarfB
Principal III

If you want to output a bit sequence at MHz frequencies with consistent timing, I would look into timer driven DMA to ODR or BSSR register of GPIOC. There are always some uncertaincies with IRQ timing such as interfering SysTick. Alternatively, you can bit-bang short sequences and avoid interrupt overhead.

Which STM32?

Your interrupt is re-entered twice per timer overflow, due to late flag clear.

Plus what KnarfB said above. MHz interrupts are foolish except in very special cases, and precision timing in 32-bitters is to be achieved using hardware. I wouldn't DMA into GPIO's output register (see below); I would DMA into timer's registers, probably using preloaded CCRx. Or, even better, I would use what's intended for serialization: SPI, I2S.

Plus never change ODR in interrupt, you'll risk atomicity issues. Use BSRR instead.

JW

MDrac.1
Associate III

Thanks for the answers!

I'm using an STM32F407 discovery board.

I've managed to get it working using the method suggested in this article (from the link you referenced).

If someone else is interested in my solution, I've added a screenshot of how my interrupt routine works. Otherwise you can take look at the Github link provided above.

As i'm starting to become aware of the limitations of my approach I'm gonna start looking into DMA, SPI and I2S. Thanks for the advice!

0693W000007EihUQAS.png