Hello, I am new to to this forum and am looking for help regarding timer issue. I am using a 18F4523 with a 4Mhz clock. Timer 0 is configured for 8 bit 1/64 prescaler (16.384ms/tick) which I am displaying hour:min:sec to LCD display. The problem is that the time is 52 seconds faster every minute. I have gone over the code umpteen times and do not no why it is acting as it is. The object of the program is to condition a device at a certain temperature for 3 days then test the device and continue for the next 5 days testing every day. See code for possible error.
Code:
'Define LCD registers and bits
DEFINE LCD_DREG PORTD
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 1
low PORTE.2
pause 100
TRISB.0 = 1 ' Set PORTB bit 0 as input external pullups
TRISB.1 = 1 ' Set PORTB bit 1 as input external pullups
TRISB.2 = 1 ' Set PORTB bit 2 as input external pullups
TRISB.3 = 0 ' Set PORTB bit 3 as output
TRISB.4 = 0 ' Set PORTB bit 4 as output
TRISB.5 = 0 ' Set PORTB bit 5 as output
' Set TMR0 to interrupt every 16.384 milliseconds
INTCON = $E0 ' Enable TMR0 interrupts
TMR0IF var INTCON.2 ' Timer0 interrupt flag
T0CON = $45 ' Set timer0 register - timer off,
' internal instruction clock, 1:64 prescale
TMR0ON var T0CON.7 ' Timer0 on bit
' Timer 1 used to blink LEDs
' Set TMR1 to interrupt every 500 milliseconds
T1CON = $31 ' Set prescaler to 1:8 and timer1 on
TMR1IF var PIR1.0 ' Timer1 interrupt flag
TMR1ON var T1CON.0 ' Timer1 on bit
PIE1.0 = 1 ' Timer1 enabled
TMR1H = $0B ' preset for timer1 MSB register
TMR1L = $DC ' preset for timer1 LSB register
TMR1IF = 0 ' Clear timer1 interrupt flag
ADCON1 = $0F ' Set channels all digital
'---------------------------Declare Variables-----------------------------------
reset_pb var PORTB.0 ' 4.7K external pullup resistor Reset button
cycle_pb var PORTB.1 ' 4.7K external pullup resistor Inc Cycle button
alarm_in var PORTB.2 ' 4.7K external pullup resistor Alarm indication
done_LED var PORTB.3 ' Done indication LED
cond_LED var PORTB.4 ' Condition LED
alrm_LED var PORTB.5 ' Alarm from temperature controller LED
hour Var byte ' Define hour variable
minute Var byte ' Define minute variable
second Var byte ' Define second variable
ticks Var byte ' Define pieces of seconds variable for timer0
ticks1 var byte ' Define pieces of seconds variable for timer1
update Var bit ' Define variable to indicate update of LCD
i Var byte ' Debounce loop variable
cond_days var byte ' Days of conditioning = 60
cycles var byte ' Test cycles = 10
do_once var bit ' Only do one time flag
do_once1 var bit ' Only do one time flag
ready var bit ' Flag for cycles push button ready
counts var byte ' Counter for alarms
hr var bit ' Flag to indicate 24hrs has passed
timer1 var bit ' Flag to blink LED's
hour = 0 ' Reset hour
minute = 0 ' Reset minute
second = 0 ' Reset second
low done_LED ' Turn off LED
low cond_LED ' Turn off LED
low alrm_LED ' Turn off LED
update = 1 ' Set to update LCD display
do_once = 0 ' Reset flag
do_once1 = 0 ' Reset flag
counts = 0 ' Reset flag
read 100, cond_days ' Load condition days from memory
read 101, cycles ' Load cycles from memory
On Interrupt Goto ISR ' Jump to interrupt service routine
main:
if reset_pb = 0 then ' Reset button pressed
cond_days = 0
cycles = 0
second = 0
minute = 0
hour = 0
low done_LED
low cond_LED
low alrm_LED
do_once = 0 ' Flag for temp in range
do_once1 = 0 ' Flag for temp out of range
update = 1
endif
If update = 1 Then ' Check for time to update screen
INTCON = $00 ' No interrupts during lcdout write
lcdout,$FE,1
lcdout,$FE,$C0," ",dec2 hour, ":",dec2 minute,":",dec2 second
lcdout,$FE,$94," CONDITION DAYS: ",dec cond_days
lcdout,$FE,$D4," TEST CYCLES: ", dec cycles
update = 0 ' Screen updated
INTCON = $E0 ' Enable interrupts
Endif
if cycles = 5 and cond_days = 8 then ' Condition for 3 days and
TMR0ON = 0 ' cycle for 5 = 8 total days
TMR1ON = 0
INTCON = $00
low cond_led
high done_led
goto main
endif
if alarm_in = 0 then
if do_once1 = 0 then ' Temperature out of range
TMR0ON = 0 ' Turn off timer0
TMR1ON = 0 ' Turn off timer1
high alrm_LED
low done_LED
low cond_LED
do_once = 0
do_once1 = 1
endif
endif
if alarm_in = 1 then ' Temperature in range
if do_once = 0 then
T0CON = $C5 ' Turn on timer 0, 8 bit, 1/64 prescaler
TMR1ON = 1 ' Turn on timer 0
TMR1IF = 0 ' Clear timer 0 interrupt flag
low alrm_LED
do_once = 1
do_once1 = 0
endif
endif
if hr = 1 then
if do_once = 1 then
T0CON = $25
cond_days = cond_days + 1
write 100,cond_days
second = 0
minute = 0
hour = 0
do_once = 0
if cond_days > 3 then ready = 1 ' change according to test requirement
endif
hr = 0
endif
if cond_days > 3 and cycles < 6 then ' Change according to test requirements
if ready = 1 then ' 24 hours passed ready for cycle
T0CON = $25 ' Set timer0 register - timer off, internal instruction clock, 1/64 prescale
if cycles < 6 then ' Change according to test requirements
if cycle_pb = 0 then
gosub Debounce
cycles = cycles + 1
write 101, cycles
second = 0
minute = 0
hour = 0
low done_LED
do_once = 0
ready = 0
update = 1
endif
endif
endif
endif
if timer1 = 1 then
if cond_days < 9 then ' Change according to test requirements
if ready = 1 then
low cond_led
else
toggle cond_LED
endif
endif
if cond_days > 3 and cycles < 6 then ' Change according to test requirements
if ready = 1 then
toggle done_LED
endif
endif
timer1 = 0
endif
goto main
' Interrupt routine to handle each timer tick
Disable ' Disable interrupts during interrupt handler
ISR:
if TMR0IF = 1 then
ticks = ticks + 1 ' Count pieces of seconds
If ticks < 61 Then tiexit ' 61 ticks per second (16.384ms per tick)
ticks = 0
' One second elasped - update time
second = second + 1
If second > 59 Then
minute = minute + 1
second = 0
If minute > 59 Then
minute = 0
hour = hour + 1
if hour >= 24 then hr = 1 ' Set flag 24hrs passed
endif
endif
update = 1 ' Set to update LCD
endif
if TMR1IF = 1 then
timer1 = 1
TMR1H = $0B ' preset for timer1 MSB register
TMR1L = $DC ' preset for timer1 LSB register
TMR1IF = 0
endif
resume
tiexit:
TMR0IF = 0 ' Reset timer interrupt flag
TMR0H = $00
TMR0L = $00
resume
debounce:
For i = 1 to 25
Pause 10 ' 10ms at a time so no interrupts are lost
Next i
Resume
end
Thanks mfsparky
Bookmarks