View previous topic :: View next topic |
Author |
Message |
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
Simple tempo routine => Glitch |
Posted: Tue Oct 05, 2010 11:03 am |
|
|
Hello!
I've got a very simple tempo routine which has a glitch when the timer overflow.
The micro is a 16F54 (no laugh!!!).
I've stripped my code to the minimum:
Code: | while(TRUE)
{
// Increment tick.
NewTmr = TMR0;
if(NewTmr>=OldTmr)
DiffTmr = NewTmr-OldTmr;
else
DiffTmr = (255-OldTmr)+NewTmr+1;
OldTmr = NewTmr;
TempoLED += DiffTmr;
if(TempoLED>=30)
{
TempoLED = 0;
LEDToggle();
}
} |
All the variables are unsigned int8 excepted TempoLED which is an unsigned int16.
This code toggle an LED at ~1Hz.
There is a glitch every 8 seconds. 8 seconds is the time for the Timer0 to overflow.
I suppose that the problem is in the DiffTmr calcul, but I don't see it ...
Any ideas?
Thanks,
Franck. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 05, 2010 11:15 am |
|
|
I didn't look closely at your program, but I remembered this thread
about the PCB subtraction bug. Check your .LST file. See if you have
the bug:
http://www.ccsinfo.com/forum/viewtopic.php?t=41773
If that doesn't help, then post a complete test program with #include
for the PIC, #fuses, #use delay(), and a main(), and all variable
declarations. Also post your compiler version. |
|
|
Franck26
Joined: 29 Dec 2007 Posts: 122 Location: Ireland
|
|
Posted: Tue Oct 05, 2010 12:01 pm |
|
|
Thanks PCM!!!
It was the same bug.
The PIC16F54 doesn't have the SUBLW opcode (same as 16F57).
For reference my compiler version is 4.107.
Here is my code using the workaround given by Ttelmah ( http://www.ccsinfo.com/forum/viewtopic.php?t=41773 )
Code: | unsigned int NewTmr; // Timer0 latch.
unsigned int OldTmr; // Last timer0 latched.
unsigned int DiffTmr; // DiffTmr = ABS(NewTmr-OldTmr).
unsigned int16 TempoLED;// Use for status LEDs.
while(TRUE)
{
NewTmr = TMR0;
if(NewTmr>=OldTmr)
DiffTmr = NewTmr-OldTmr;
else
DiffTmr = 255+(-OldTmr)+NewTmr+1; // DiffTmr = (255-OldTmr)+NewTmr+1;
OldTmr = NewTmr;
TempoLED += DiffTmr;
if(TempoLED>=30)
{
TempoLED = 0;
LEDToggle();
}
} |
Thanks again,
Franck. |
|
|
Ken Johnson
Joined: 23 Mar 2006 Posts: 197 Location: Lewisburg, WV
|
|
Posted: Tue Oct 05, 2010 12:37 pm |
|
|
Ummm . . .
how about just always
DiffTmr = NewTmr-OldTmr;
This always gives the correct result, even after an overflow.
Ken |
|
|
|