cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429 High speed DAC interupt + USART interrupt misses characters

rinwinte
Associate II
Posted on November 13, 2014 at 06:54

To drive my application I use two DAC in a interrupt. The data sended to the DAC needs to count up and count down between two variable(bits) so that it creates a triangular wave. The maximum value is 4095. 

The frequency of the wave needs to be around 100Hz. To create the wave I use TIM2 interrupt.

Sysclk = 180Mhz, Tim2Clk = 90Mhz. Interrupt frequency = 100Hz*(4096*2) = 819200 Hz.

Problem is that because of the interrupt frquency is 820kHz (what is really high) the Usart interupt routine misses some characters.

How can I solve this? The only thing i can come up with is to use DMA for the USART receiving. But better should be to cut the DAC loose from the CPU somehow.
11 REPLIES 11
ivani
Associate II
Posted on November 13, 2014 at 08:29

May be you could you the built-in triangle wave generator function of F4 DAC (chapter 14.3.9 from the manual).

On the other side you could implement USART support via DMA and not using an interrupt for it at all. However, I doubt that since you are missing interrupts it means that the DAC is flooding the CPU by interrupt request and anyway your system performance will be poor.
rinwinte
Associate II
Posted on November 13, 2014 at 08:36

I have thought at the inbuild triangle wave funtion but you only have a limited amount of different amplitudes. And I need to have the option for all the amplitudes.

I am afraid too that the DMA option for USART not resolve the flooding problem of the interrupt where the value calculations and DAC writing takes place

frankmeyer9
Associate II
Posted on November 13, 2014 at 08:44

Sysclk = 180Mhz, Tim2Clk = 90Mhz. Interrupt frequency = 100Hz*(4096*2) = 819200 Hz. Problem is that because of the interrupt frquency is 820kHz (what is really high) the Usart interupt routine misses some characters.

 

...

 

How can I solve this?

 

By reducing the interrupt frequency, and the output rate, which is too high.

Check the datasheet. The DAC has output settling times in the range of several microseconds, so it can't follow anyway.

ivani
Associate II
Posted on November 13, 2014 at 08:55

Another solution is using DMA for the DAC.

You could precompute an array of 8190 values (or even a lower number as @fm proposes) and put the DMA in a circular mode.
rinwinte
Associate II
Posted on November 13, 2014 at 09:26

Is it possible to start and stop from a certain point in that 8192 sizes array.

like array[50] to array[2056] via DMA?

I can not find anything about the settling sime. Only that it depends on the power supply voltage and the analog output load. For now the DAC can follow the speed

frankmeyer9
Associate II
Posted on November 13, 2014 at 09:56

I can not find anything about the settling sime.

0690X00000605Z5QAI.png

From DM00071990.pdf, STM32F427xx/STM32F429xx Datasheet.

EDIT: freakin' forum cannot display images ...

Look at given document, page 161.

rinwinte
Associate II
Posted on November 13, 2014 at 10:53

so the settling time is max 6mircoseconds. Which meens that 1/819200=1.22microseconds is indeed too fast. So the interupt frequency needs to be at least 5 times slower-> 1.22*5 = 6.1microseconds.

Am I correct?

What is a good interrupt speed?

frankmeyer9
Associate II
Posted on November 13, 2014 at 11:50

6 microseconds is the maximum, for full swing and max. capacitive load.

You DAC feeding frequency will depend on the accuracy of the output curve you need (which I don't know).It is not necessarily an interrupt frequency, you can prepare a value table and feed it per DMA into the DAC.

But interrupts at 800kHz is absurdly high, you waste most of CPU performance for interrupt entry + exit.

ivani
Associate II
Posted on November 13, 2014 at 12:09

No, it is not possible to start and stop the DMA on arbitrary point in a circular mode. But it could be done in several other ways:

- If a single (or few periods) are needed then you could use larger buffer holding the signal for the whole time needed and run it only once.

- Or, use the DMA in dual buffer mode with an interrupt at end of each transfer. Then you could program each of the transfers to start/stop at desired point but you will have only one interrupt per one signal period.

It will depend on your exact requirements.