Code:
'
' Buttons.bas
' ---------------
' by Melanie
' written on a Laptop in a lunchbreak in a Cafe Nero
' in Londons famous Regent Street... 7th June 2006
'
' A simple demonstrator as to what can be done
' with just ONE Button and an LCD...
' Some Code stolen from OLYMPIC TIMER
'
'
' Device Programming Options
' --------------------------
@ DEVICE pic16F628, INTRC_OSC_NOCLKOUT
' System Clock Options
@ DEVICE pic16F628, WDT_ON ' Watchdog Timer
@ DEVICE pic16F628, PWRT_ON ' Power-On Timer
@ DEVICE pic16F628, BOD_ON ' Brown-Out Detect
@ DEVICE pic16F628, MCLR_OFF ' Master Clear Options (Internal)
@ DEVICE pic16F628, LVP_OFF ' Low-Voltage Programming
@ DEVICE pic16F628, CPD_OFF ' Data Memory Code Protect
@ DEVICE pic16F628, PROTECT_OFF ' Program Code Protection
'
' Hardware Defines
' ----------------
'
' LCD Display
' -----------
Define LCD_DREG PORTB ' Port for LCD Data
Define LCD_DBIT 4 ' Use upper 4 bits of Port
Define LCD_RSREG PORTB ' Port for RegisterSelect (RS) bit
Define LCD_RSBIT 3 ' Port Pin for RS bit
Define LCD_EREG PORTB ' Port for Enable (E) bit
Define LCD_EBIT 2 ' Port Pin for E bit
Define LCB_BITS 4 ' Using 4-bit bus
Define LCD_LINES 2 ' Using 2 line Display
Define LCD_COMMANDUS 2000 ' Command Delay (uS)
Define LCD_DATAUS 50 ' Data Delay (uS)
'
' Buttons
' -------
MyButton var PortB.0
'
' Software Defines
' ----------------
AMPMFlag var BYTE ' Flag for 12/24 Hour Mode 0=24, 1=12
' - Yes I know it's a BYTE but I can't be bothered
ButtonPress var BYTE ' Button Counter Variable
DataA var BYTE
Hours var BYTE
Hundredths var BYTE
MenuStep var BYTE ' Status Indicator for Menu Display
Minutes var BYTE
Seconds var BYTE
TMR1Cal var BYTE ' Timer Calibration Value
TMR1CalAR var BYTE ' Timer Advance/Retard Indicator
TMR1RunOn var WORD ' variable holding TMR1 Run-On value
'
' EEPROM Settings
' ---------------
Data @0,0 ' Advance/Retard Indicator
Data 0 ' Calibration Value
Data 0 ' 12/24 Hour Flag
'
' Software Constants
' ------------------
LongPress con 20 ' Change this value for desired SET
' function trip-point in 50mS steps
' Currently set for 1 Second
TMR1CalMax con 100 ' Maximum adjustment (+/-100uS per 10mS interrupt)
TMR1Preset con $D910 ' 10mS Timer Reload value, offset by 20uS
' to allow for TMR1 Setting Calculations
'
' Initialise PIC
' --------------
TRISA=%00000000 ' PortA I/O Configuration
TRISB=%00000001 ' PortB I/O Configuration
CMCON=%00000111 ' Comparators OFF
OPTION_REG.7=0 ' Enable weak Pull-Ups (used for PressButton)
'
' Initialise Main Program
' -----------------------
Pause 2000 ' Timeout for LCD Hardware to wake-up...
Read 0,TMR1CalAR ' Read Calibration Advance/Retard Indicator
Read 1,TMR1Cal ' Read Calibration Value
Read 2,AMPMFlag ' It's what it says...
Hundredths=0 ' Reset Timer Counter variables
Seconds=0
Minutes=0
Hours=0
'
' Initialise TMR1 Interrupts
' --------------------------
Gosub SetTimer ' Set the Timer for next 10mS Interrupt
On Interrupt goto TickCount
PIE1.0=1 ' Enable TMR1 Interrupts
INTCON.6=1 ' Enable all unmasked Interrupts
INTCON.7=1 ' Enable Global Interrupts
DisplayRestart:
LCDOut $FE,1 ' Clear Display
'
' Main Program Loop
' -----------------
Enable
DisplayLoop:
LCDOut $FE,$0C
If AMPMFlag=0 then
'
' Here we have got a 24 Hour Clock Display
' ----------------------------------------
LCDOut $FE,$84,DEC2 Hours,":",DEC2 Minutes,":",DEC2 Seconds
else
'
' and here we have a 12 Hour Clock Display
' ----------------------------------------
LCDOut $FE,$82
DataA=Hours
If DataA=0 then DataA=12
If DataA>12 then DataA=DataA-12
If DataA<10 then LCDOut " "
LCDOut #DataA,":",DEC2 Minutes,":",DEC2 Seconds," "
If Hours>11 then
LCDOut "PM"
else
LCDOut "AM"
endif
endif
'
' Check For Button Press
' ----------------------
Gosub GetButton
'
' Toggle 24 Hour Mode
' -------------------
If ButtonPress=1 then
AMPMFlag=AMPMFlag^1
Write 2,AMPMFlag
Goto DisplayRestart
endif
If ButtonPress<>2 then goto DisplayLoop
Disable
'
' Setup Mode
' ----------
LCDOut $FE,1,"Set Time Please:"
LCDOut $FE,$C4,DEC2 Hours,":",DEC2 Minutes,":",DEC2 Seconds,$FE,$C5
MenuStep=0
MenuLoop:
Gosub GetButton
'
' SET Mode
' --------
If ButtonPress=2 then
MenuStep=MenuStep+1
If MenuStep=3 then
LCDOut $FE,1,$FE,$83,"Thank You",$FE,$C0,"Have a Nice Day"
Pause 2000
Goto DisplayRestart
endif
endif
If ButtonPress=1 then
'
' Hours
' -----
If MenuStep=0 then
Hours=Hours+1
If Hours>23 then Hours=0
LCDOut $FE,$C4,DEC2 Hours
endif
'
' Minutes
' -------
If MenuStep=1 then
Minutes=Minutes+1
If Minutes>59 then Minutes=0
LCDOut $FE,$C7,DEC2 Minutes
endif
'
' Seconds
' -------
If MenuStep=2 then
Seconds=Seconds+1
If Seconds>59 then Seconds=0
LCDOut $FE,$CA,DEC2 Seconds
endif
endif
'
' Ensure Cursor is in a nice place...
' --------------------------------
LCDOut $FE,$0E
If MenuStep=0 then
LCDOut $FE,$C5
else
If MenuStep=1 then
LCDOut $FE,$C8
else
LCDOut $FE,$CB
endif
endif
Goto MenuLoop
'
' Subroutine weighs-up users finger
' in multiples of 50mS
' Constant LONGPRESS determines boredom level
' -------------------------------------------
' on Exit...
' ButtonPress=0 - No Press
' ButtonPress=1 - Short Press
' ButtonPress=2 - Long Press
GetButton:
ButtonPress=0
While MyButton=0
If ButtonPress<255 then ButtonPress=ButtonPress+1
Pause 50 ' This is also our Debounce value
If ButtonPress=>LongPress then LCDOut $FE,$0F
Wend
If ButtonPress>0 then
If ButtonPress=>LongPress then
ButtonPress=2
else
ButtonPress=1
endif
endif
Return
'
' Subroutine Loads TMR1 values
' ============================
SetTimer:
T1CON.0=0 ' Stop the Clock
TMR1RunOn.Highbyte=TMR1H ' Load the Run-On (Over-Run) value (if any)
TMR1RunOn.Lowbyte=TMR1L
TMR1RunOn=TMR1Preset+TMR1RunOn ' Calculate the New (adjusted) value for TMR1
If TMR1CalAR=0 then ' Calibration ADVANCE (add) or RETARD (subtract)
TMR1RunOn=TMR1RunOn+TMR1Cal
else
TMR1RunOn=TMR1RunOn-TMR1Cal
endif
TMR1H=TMR1RunOn.Highbyte ' Save new values to TMR1
TMR1L=TMR1RunOn.Lowbyte
T1CON.0=1 ' Restart the Clock
PIR1.0=0 ' Reset TMR1's Interupt Flag
Return
'
' Timer Interrupt Handler
' =======================
TickCount:
Gosub SetTimer ' Set the Timer for next 10mS Interrupt
Hundredths=Hundredths+1 ' Increment 10mS Seconds Counter
If Hundredths>99 then
Hundredths=0
Seconds=Seconds+1
' Increment the Seconds
If Seconds>59 then
Seconds=0
Minutes=Minutes+1
' Increment the Minutes
If Minutes>59 then
Minutes=0
Hours=Hours+1
' Increment the Hours
If Hours>23 then Hours=0
endif
endif
endif
Resume
End
Bookmarks