' Name : T246_1934X.pbp ' Compiler : PICBASIC PRO Compiler 2.6 ' Assembler : MPASM ' Target PIC : 40-pin 16F1934 or similar ' Hardware : LAB-X1 Experimenter Board ' Oscillator : 4MHz external crystal ' Keywords : LCDOUT ' Description : PICBASIC PRO program to demonstrate using Timer2 for a ' 24 hour format clock. Time is shown on the LCD as Time = 11:14 with ' hours : minutes. ' ' Define LCD pins Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 ' setup vars for clock Time Var Word ' accumulates TMR2 to PR2 match counts Minutes Var Byte ' minutes Hours Var Byte ' hours Match Var PIR1.1 ' TMR2 to PR2 match interrupt flag bit IocFlag Var INTCON.0 ' portb int-on-change flag bit Gosub Init ' jump to hardware initialization routine Lcdout $fe,1,"Time = ", #Hours DIG 1,#Hours DIG 0,":",#Minutes DIG 1,#Minutes DIG 0 ' setup & start TMR2 after Lcdout T2CON = %01110110 ' set 1:16 prescale, 1:15 postscale, TMR2 on ' =============\ Main Program Start /============= ' Main: ' every 60mS the TMR2IF flag is set, and this routine is entered. ' Plenty of time to do other stuff. If Match = 1 Then ' has TMR2 matched PR2? (should happen every 60mS) Match = 0 ' yes. clear TMR2 to PR2 match flag bit PIR1.1 Time = Time + 1 ' increment 60mS count If Time = 1000 Then ' has 60 seconds (1000*60mS) passed? Time = 0 ' yes. clear count Minutes = Minutes + 1 ' increment Minutes If Minutes = 60 Then ' roll-over from 59 to 0 Minutes = 0 ' zero Minutes count Hours = Hours + 1 ' and increment Hours count If Hours = 24 Then ' roll-over from 23 to 0 Hours = 0 ' zero Hours count Endif Endif ' Update time on LCD every 60 seconds Lcdout $fe,$87,#Hours DIG 1,#Hours DIG 0,":",#Minutes DIG 1,#Minutes DIG 0 Endif Endif ' test for key press If IocFlag Then ' if keys SW13, 14, 15 or 16 were pressed, Gosub GetKeys ' get the button/buttons pressed Endif Goto Main ' ===========\ Get Keypad Switch Presses /=========== ' GetKeys: Pause 500 ' crude debounce for key press ' SW13 increments Hours If IOCBF.4 Then ' IOCBF.4 = 1 when low edge detected on RB4 While PORTB.4 = 0 ' wait for key release Wend ' Hours = Hours + 1 : Time = 0 If Hours = 24 Then Hours = 0 Endif ' SW14 increments Minutes If IOCBF.5 Then ' IOCBF.5 = 1 when low edge detected on RB5 While PORTB.5 = 0 ' wait for key release Wend ' Minutes = Minutes + 1 : Time = 0 If Minutes = 60 Then Minutes = 0 Endif ' SW15 zeros Time "tick" counter If IOCBF.6 Then ' IOCBF.6 = 1 when low edge detected on RB6 While PORTB.6 = 0 ' wait for key release Wend ' Time = 0 Endif ' SW16 rests clock to 12:00 If IOCBF.7 Then ' IOCBF.7 = 1 when low edge detected on RB7 While PORTB.7 = 0 ' wait for key release Wend ' Hours = 12 : Minutes = 0 : Time = 0 Endif IOCBF = 0 ' reset all int-on-change bits on exit IocFlag = 0 ' Update LCD on each change Lcdout $fe,$87,#Hours DIG 1,#Hours DIG 0,":",#Minutes DIG 1,#Minutes DIG 0 Return ' ===========\ Hardware Initialization Routine /=========== ' Init: ANSELA = 0 ' porta all digital ANSELB = 0 ' portb all digital ANSELD = 0 ' portd all digital ANSELE = 0 ' porte all digital OPTION_REG.7 = 0 ' enable PORTB pullups PORTB = 0 ' RB3 low TRISB = %11110111 ' RB3 = 0 for output to keys 13, 14, 15, 16 WPUB = %11110000 ' weak pull-ups on for ----> RB4, 5, 6, 7 IOCBP = 0 ' positive edge disabled IOCBN = %11110000 ' negative edge int-on-change enabled for keys TRISD = 0 ' PORTD all outputs INTCON = 0 ' not using interupts. Just monitoring int flag bits Time = 0 ' clear TMR2 to PR2 match counter Hours = 10 ' set clock starting hour to 13 here Minutes = 16 ' set clock starting minutes to 56 here ' TMR2 increments from 0 until it matches the value in the PR2 register. ' The match automatically resets Timer2 and sets the Timer2 interrupt flag ' bit PIR1.1. PR2 = 249 ' 0 to 249 = 250. 250*16*15*1uS=60mS Match = 0 ' clear PIR1.1 match flag bit Pause 100 ' Wait for LCD to start Return ' Return to caller End