Consistent Loop Delay with Counter Wrap-Around
coryco2
Posts: 107
I am looking for the best way to insert a pause into a repeat loop of code that will cause each loop to take "ms" before the "next command" is executed. (Other not shown commands in the loop vary in their execution time and may include loopstart:= cnt to reset the loopstart time.) I came up with with the following two approaches, and would appreciate any comments or suggestions. I'm looking to get an accurate, consistent delay, and avoid problems with system counter wrap-around.
ms:=50 REPEAT loopstart:= cnt 'code with variable execution time REPEAT UNTIL ||(cnt - loopstart) => ((clkfreq/1000)*ms) 'Approach 1 '...next command waitcnt (((clkfreq/1000)*ms) + loopstart) 'Approach 2 '...next command
Comments
You just have to prevent your code from running longer than your intended delay
It will recover on the cases above, the counter never waits for more than ~53 seconds!
If you want to avoid that, another test to check if the cnt is already ahead of the wait-point is needed.
The overtime will be compensated in the next loop(s).
Andy
If you wanted to drop into low-power mode using waitcnt, you would need some extra safety margin, something like: I could get it to fail (lock while the counter does a complete roll-over) with a safety margin of 2500. 2800 seems to be working for me, but I would bump that up if using this in production code. Note that you could wrap the safety value and dt into another variable...it would be a tiny bit faster, at the expense of another variable and setup.
Jonathan