Hi All!
I have a system clock 8Mhz so sycle time = 125ns
For delay 1000us i need 1000/0.125 = 8000 cycles
when i use __delay_cycles(8000) i get 1250us and i need exact timing.
How do i cope with the problem?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi All!
I have a system clock 8Mhz so sycle time = 125ns
For delay 1000us i need 1000/0.125 = 8000 cycles
when i use __delay_cycles(8000) i get 1250us and i need exact timing.
How do i cope with the problem?
You could build a custom delay function in assembly. One simple approach is to make the function a string of nop instructions with a ret at the end. At the beginning of the function use a cycle parameter to figure out which nop instruction to jump to in the nop list. From there you just execute nops until you return, which creates your delay. You will have to figure out how many cycles it takes to exit/enter the function, as well as jump to the specified nop in order to make it work correctly.
That is the most simplistic approach. You can improve on this by breaking it into loops and such. However, the more enhancements and decision logic you add to the function, the more the minimum function delay will be. Also note that creating a custom delay function is highly dependent on your core (normal, X, or X2), as the cycle times for different instructions have been improving.
But to be honest, the reason for this assembly function was that for a long time the __delay_cycles intrinsic didn't exist, so I had to do it myself. Now that IAR added this intrinsic, I would rather use their built in function, which works great for small nanosecond/microsecond delays.
If you really need an accurate 1ms delay, I would recommend using a timer.
Just for a sanity check, I did a little experiment with the __delay_cycles() with different cycle inputs using the simulator for one of IAR's sample projects (a 5419 part). It seems to be generating the correct delay regardless of what I put in. I tried various values: 3, 10, 20, 100. Honestly, I thought I remembered playing with this intrinsic when it first came out and discovering that it wasn't exact (and would error on the side of too much delay; which is much preferable to too little delay in my opinion). Perhaps they have cleaned it up with newer versions.
Either way, with the latest version (Compiler 4.21.2) it seems to be doing the right thing. The algorithm seems to be adaptive so that it will add whatever nops are necessary on top of the loop if there are odd cycles with respect to the loop.
Are you using the latest version of MSP430 IAR (4.21.2)?
If so, what method did you use to determine that the loop was taking too long? Did you use the cycle counter, or measure with an oscilloscope? In either case, you might try turning off interrupts before you do the measurement.
I think __delay_cycles(8000); emits assembly code that takes exactly 8000 MCLKs to execute. But if interrupt was eanabled and an interrupt was requested during that time, the ISR will take an unknown number of additional MCLKs.
**Attention** This is a public forum