' Resettable timer
'
' TMR0 used for timekeeping
' RB0 is the button input (start/stop)
' MCLR will reset the time
' ---------------------------------------------------------------
' LCD Variables required by <libs\interface\4BitLCD.bas>
Dim LCD_D4 @ PORTD.0 As Boolean, LCD_D4_DIR @ TRISD.0 As Boolean
Dim LCD_D5 @ PORTD.1 As Boolean, LCD_D5_DIR @ TRISD.1 As Boolean
Dim LCD_D6 @ PORTD.2 As Boolean, LCD_D6_DIR @ TRISD.2 As Boolean
Dim LCD_D7 @ PORTD.3 As Boolean, LCD_D7_DIR @ TRISD.3 As Boolean
Dim LCD_E @ PORTA.1 As Boolean, LCD_E_DIR @ TRISA.1 As Boolean
Dim LCD_RW @ PORTA.2 As Boolean, LCD_RW_DIR @ TRISA.2 As Boolean
Dim LCD_RS @ PORTA.3 As Boolean, LCD_RS_DIR @ TRISA.3 As Boolean
Include <libs\interface\4BitLCD.bas> ' load the LCD library
' --------------------------------------------------------------
' Hardware definitions
Dim btn@PORTB.0 As Boolean ' The button is at PORTB Bit 0
' Global variables
Dim run_mode As Boolean ' 1 = run mode
Dim T0Overflows As uByte ' keeps track of TMR0 overflows
Dim elapsedSeconds As uByte ' timer variable
Dim elapsedMinutes As uByte ' timer variable
Dim elapsedHours As uByte ' timer variable
Dim updateDisplayFlg As Boolean ' signal the Display Task to update the display
Dim buttonState As Boolean ' holds the state of the button on the last pass
' The program starts here
Sub main()
Call init() ' initialize everything here
While 1
clrwdt ' clear the watchdog timer
Call buttonCheck() ' react to a button press
Call updateDisplay() ' update the display
End While
End Sub
' handel a TMR0 interrupt
Sub isr() IntHigh
If TMR0IF=1 Then
TMR0IF=0 ' clear the interrupt flag
If run_mode=1 Then ' do not update the time if we are not in run mode
T0Overflows = T0Overflows + 1
If T0Overflows > 61 Then ' 61 overflows in 1S
T0Overflows = T0Overflows - 61 ' remove 100mS worth of overflows
updateDisplayFlg=1 ' it's time to update the display
elapsedSeconds = elapsedSeconds+1 ' add to the seconds
If elapsedSeconds=60 Then
elapsedSeconds=0 ' seconds overflowed
elapsedMinutes=elapsedMinutes+1 ' add to the minutes
If elapsedMinutes=60 Then
elapsedMinutes=0 ' minutes overflowed
elapsedHours=elapsedHours+1 ' add to the hours
End If
End If
End If
End If
End If
End Sub
' if the user has pressed the button, then toggle the running mode
' of the timer. Also wait for the user to release the button before
' registering another button press.
Sub buttonCheck()
If buttonState=0 Then
' the button was not previously pressed
If button(1)=1 Then ' did the user press the button?
btg run_mode ' yes so toggle the running mode
buttonState=1 ' the button is currently pressed
End If
Else
' the button was previously pressed
If button(0)=1 Then buttonState=0 ' the button has been released
End If
End Sub
Sub init()
' Timer0 Configuration:
' Timer0: ON
' 8 Bit Read/Write Mode
' Clock Source: Internal instruction cycle
' Edge Select: High to Low
' Prescaler: ON
' Prescale Value: 1:64
' Time/Bit: 64u S
' Overflow: 16.384m S
' Overflows/Second: 61.03516
T0CON=0xD5
ADCON1=0x87 ' ADC off
Call LCDinit() ' initialize the LCD
' Interrupt configuration:
RCON = RCON And 127
TMR0IF=0: TMR0IE=1 ' Timer 0 Interrupt enabled
GIE=1
' initialize variables
run_mode=0 ' not in run mode to start
T0Overflows=0 ' no overflows yet
elapsedSeconds=0 ' reset the timer
elapsedMinutes=0 ' reset the timer
elapsedHours=0 ' reset the timer
updateDisplayFlg=1 ' force an LCD update to begin with
buttonState=0 ' button has not yet been pressed
End Sub
Sub updateDisplay()
Dim s(10) As String
If updateDisplayFlg=1 Then
updateDisplayFlg=0 ' reset the flag
Call LCDcls()
Call str(elapsedHours,s): Call LCDputs(s): Call LCDputc(":")
Call str(elapsedMinutes,s): Call LCDputs(s): Call LCDputc(":")
Call str(elapsedSeconds,s): Call LCDputs(s)
End If
End Sub
' Return 1 if the selected state is true
'
' Parameters:
' WREG The value (or button state) to look for
Function button(WREG As uByte)
Dim val As uByte
val=WREG
Repeat 5 ' check 5 times
If PORTB.0<>val.0 Then
val=0: return ' return FALSE
End If
delayms(10) ' wait for 10 milliseconds
End Repeat
val=1 ' the button is in the requested position
End Function val