I am having a big headache now. I have been trying to build a clock keeping time with Timer0. Using the Timer0 module supplied by Darryl and by interrupt and updating the clock registers in my program. However, may be due to my lack of knowlegde in handling interrupts, my clock registers which are public variables in SF are corrupted. I am not sure how to solve this. I have tried context saving several registers which I think important but, the variables return wrong results! I hope someone can give some comment on this. And it also appears to me that the clock sometimes tripped. I am not sure if I have used interrupt correctly.
Code: Select all
Device = 18f2525
Clock = 20
#option ISR_SHADOW = false
Include "Timer0.bas" 'found in SF wiki
Include "utils.bas"
Const Segment() As Byte = ( $7C ,$88, $28, $64, $22, $2, $78, $0, $20, $10)
Dim LED As PORTC.3
Dim SinkPin As PORTA.0
Public Dim RSeconds As Byte
Public Dim RMinutes As Byte
Public Dim RHours As Byte
Public Dim ActualSeconds As Byte
Public Dim ActualMinutes As Byte
Public Dim ActualHours As Byte
Dim Index As Byte
Dim Tick As Boolean
Sub SendByte(ByVal B As Byte)
TRISB = $00
PORTB = B
End Sub
Sub IncreaseTimer()
'Keeping the Actual timer
'all the variables storing the time values are GLOBAL
Inc(ActualSeconds)
'checks if actualseconds = 60
If ActualSeconds = 60 Then
Inc(ActualMinutes)
'reset the actual seconds
ActualSeconds = 0
End If
'checks if actualminutes = 60
If ActualMinutes = 60 Then
Inc(ActualHours)
'reset the actual minutes
ActualMinutes = 0
End If
'reset if = 24
If ActualHours = 24 Then
ActualHours = 0
End If
End Sub
Sub IncreaseRunTime()
'Keeping the RunTime timer
'all the variables storing the time values are GLOBAL
Inc(RSeconds)
'checks if actualseconds > 60
If RSeconds >= 60 Then
Inc(RMinutes)
'reset the actual seconds
RSeconds = 0
End If
'checks if actualminutes > 60
If RMinutes >= 60 Then
Inc(RHours)
'reset the actual minutes
RMinutes = 0
End If
End Sub
Sub InitRegisters()
ActualSeconds = $00
ActualMinutes = $00
ActualHours = $00
RSeconds = $00
RMinutes = $00
RHours = $00
End Sub
'event and intterupt
Event LEDFlash()
Toggle(LED)
IncreaseTimer
Tick = true
End Event
Interrupt ISR()
Dim WREGHold, BSRHold As Byte
// If a byte receive has triggered the interrupt, then context save
// FSR0, FSR1, INF0, INDF1 and process the data byte...
BSRHold = BSR
WREGHold = WREG
Save(0, PCLATH, WREG, FSR0L, FSR0H, FSR1L, FSR1H, INDF0, INDF1, STATUS, PRODL, PRODH, TABLEPTR, TABLAT)
INTCON.7=0
If Timer0.InterruptFlag =1 Then
Timer0.SInterrupt()
EndIf
INTCON.7=1
'this segment I have no idea what it means, copied from Steven's post
Restore
WREG = WREGHold
BSR = BSRHold
End Interrupt
Sub MultiplexLED(ByVal LetterIndex As Byte)
Dim Holder As Byte
..........
End Sub
// main
Utils.SetAllDigital()
Output(LED)
'initialize
InitRegisters
Timer0.Initialize(LEDFlash)
Timer0.SetPrescaler(Timer0.PS128)
Timer0.EightBit = 0
Timer0.Preload=26473
Timer0.EnableInterrupt()
Timer0.Enabled()
Enable(ISR)
While true
'displaying the clock reading
Index = 0
While Index <= 5
MultiplexLED(Index)
Index = Index + 1
Wend
'time keeping
'with every tick increase the timer
If Tick = true Then
Tick = false 'must reset Tick as early as possible
IncreaseTimer
End If
Wend
End
Hope someone can suggest a solution. I just want to keep the time in the variables declared. And I am meeting deadlines soon!
Thanks
Liak