assembly language question
mynet43
Posts: 644
Will the following code work, regardless of whether cnt or tr_act_cnt have wrapped around?
My goal is to set a future time count, then see when cnt catches up to it. Either one could wrap before the comparison. The time difference will never be more than a few seconds. I'm timing the on-time of a signal, before I turn it off.
Thank you for your help.
Jim
My goal is to set a future time count, then see when cnt catches up to it. Either one could wrap before the comparison. The time difference will never be more than a few seconds. I'm timing the on-time of a signal, before I turn it off.
mov tr_act_cnt,cnt ' read uP count clock add tr_act_cnt,delta ' set future time... . . . other code mov temp,cnt ' read uP count clock cmp temp,tr_act_cnt wc ' see if cnt < tr_act_cnt if_c jmp :exit ' if so, leave it on
Thank you for your help.
Jim
Comments
Just a sanity check. Is this what it should look like?
Thanks again for your help.
Jim
This will not work, it's the same as compare. The trick is to ignore the carry at building the difference, and check then if the result is positive or negative:
Andy
I think your use of subtract and your comment "see if cnt =<" is not what you are looking for.
Lets say that temp was max unsigned int. Then there does not exist a cnt vaule that would set the wc flag with the code you have.
What I think you really want is to detect in the max int case of temp, values of cnt equal to max int + 1 (or 0) to be seen as past the temp value. But, also cnt values of max int + 1000 (999). But, not max int - 1000. Nor, max int + 4,000,000,000.
So, back to what Mike was saying in his first post, is you really have to give up one bit and convert to unsigned. Then, if cnt is more than 1/2 max unsigned int past a value, it is really less than.
Rocky
I think I got it now. I missed that when I looked at the example in FullDuplexSerial.
I'm glad I did the sanity check
Thanks everyone.
Jim
The other is now working.
But this is interesting How do you do a LOGIC always counter?
Jim
1. Start using the new 1.2 manual, and throw out the 1.0 manual I printed out years ago
2. Learn more about using the counters.
So here's my first cut at it:
Please let me know if I'm on the right track. If so, I really like it!
Thanks again for all your help.
Jim
I think for the instruction "mov ctra,ctra_mode" to work ctra_mode would need to be in DAT instead of CON.
Also, ctra will have the settings, so "cmp ctra,delta wc" will not have the count. I think you are looking for phsa. Also, you might have to init phsa to 0. And, frqa might need to be 1, I do not know for sure.
There is some examples in some of the tutorials that use these counters for things like timing capacitor drain times. Also, these counters work in spin as well as pasm. I would suggest getting the counter to work the way you want in spin first then porting it to pasm.
You're absolutely right about the CON vs DAT issue. I fixed that right after I sent the note.
It's obvious I didn't get it quite right this time. It looked so simple
If someone would spend 5 minutes and write me an example, it would really help.
I need to do it in assembly code because it's a time critical app tracking an encoder on an AC motor at 5000 steps per rev, and doing other processing at the same time. So every instruction counts. It would be so nice to have the counter doing some of my work.
I'll take a look at the counter document to see if I can figure it out.
Thank you for your help and support.
Jim
Not a full example but took only 2 minutes: You can set the mode/pin fields of the CTRx register with movi, movd and movs.
If the counter is enabled FRQx is added to PHSx every cycle while the mode-depending condition is true. In always mode it's always true.
Andy
Thanks so much for your 2-minute reply. It all makes sense now.
Good example of how to do it with movi.
Now I see how the three registers work together.
Thanks again.
Jim
It's amazing how well this forum works.
Thanks everyone for a great learning experience.
Jim