Problem with assembly CMP instruction and the CNT
DDS
Posts: 16
After spending way too much time debugging my code, I have a problem with this block of code. I have stripped out everything but the code that is causing the problem.
:loop2····· mov······ ST3,cycle·············· ' Calculate time delay, cycle = 1_400_000 but·not important
············· mov······ ST2,cnt
············· add······ ST2,ST3
············· mov······ ST3,cnt················· ' check to see if new CNT is greater than·CNT + 1_400_000.
············ cmp······ ST2,ST3 wc············· ' Is the time up (Set C if ST3 > ST2)
·if_nc····· jmp······ #:loop2················ ' Time is not up
I am adding a constant to the CNT each time through the loop but every 53 seconds it falls out of this loop to the code following it.
The 53-seconds is 2^32 / 80-Mhz clock.
I understand that the C flag is set when the 2nd variable is·greater than the 1st variable in the line (CMP ST2, St3 wc)
It seems that it is getting set once every 2^32 times through the loop - WHY?
Executable code attached.
Thanks for any help
Don
:loop2····· mov······ ST3,cycle·············· ' Calculate time delay, cycle = 1_400_000 but·not important
············· mov······ ST2,cnt
············· add······ ST2,ST3
············· mov······ ST3,cnt················· ' check to see if new CNT is greater than·CNT + 1_400_000.
············ cmp······ ST2,ST3 wc············· ' Is the time up (Set C if ST3 > ST2)
·if_nc····· jmp······ #:loop2················ ' Time is not up
I am adding a constant to the CNT each time through the loop but every 53 seconds it falls out of this loop to the code following it.
The 53-seconds is 2^32 / 80-Mhz clock.
I understand that the C flag is set when the 2nd variable is·greater than the 1st variable in the line (CMP ST2, St3 wc)
It seems that it is getting set once every 2^32 times through the loop - WHY?
Executable code attached.
Thanks for any help
Don
Comments
IF this is correct, then the value I add to the CNT should also be unsigned.
This would require the unsigned ADD instruction.
Thanks and let me know if I am wrong.
This avoids any problems when cnt rolls over.
But why not just use waitcnt if you're not doing anything else during the :loop? Here's the code:
It's not only less code, but it gives you 12.5ns resolution with an 80Mhz system clock.
-Phil
Thats it. After probably 5-hours of trial & error, you nailed it - Thanks.
I·kept thinking that when the addition rolled over, so did the CNT but it doesn't for a number of iterations.
Phil,
Thanks for the code snippet, this will solve it.
BTW, the reason I wasn't using the waitcnt instruction is because I am watching a clipped 60-hz signal from a transformer. When I detect a missing cycle, I need to quickly write some variables to EEPROM before the filter capacitor discharges. While I run through this loop, I also watch the state of the input pin so it is a race to see if the 60-Hz cycle finishes or it times out. I have stripped all the other code out so what I posted wasn't long and needlessly confusing.
I knew that someone on the forum would take a quick look and know see the problem.
Thanks again,
Don
One of the tricks about debugging is to manually work through some boundary conditions. That's what I did in your case. You hand simulate on paper the cases just before or just after a rollover or similar change occurs. Often it will either show you the problem or at least drop hints of where else the problem may be.