;----------------------------------------------------------------------; ; WKTIM4M.ASM Pushbutton toggles clock on and off, time on LCD 4 MHz ; ;----------------------------------------------------------------------; ; Note: must add additional time digit to run over 99 hrs. ; .-----------. ; -|RA2 RA1|----[LCD E] ; -|RA3 RA0|----[LCD RS] ; -|RA4 OSC1|--|X|-||--- gnd ; V+ ---|MCLR OSC2|--|X|-||--- gnd ; gnd ---|Vss Vdd|--- V+ ; [LCD D4]----|RB0 RB7|- X = 4.096 MHz xtal 20 pfd ; [LCD D5]----|RB1 RB6|- V+ = 4.5 or 5 Volts ; [LCD D6]----|RB2 RB5|- ; [LCD D7]----|RB3 RB4|---[PB]--- gnd ; '-----------' ; PIC16F84 -[PB]- pushbutton ; LCD pin connections: ; 1 - gnd ground 2 - Vcc V+ 3 - contrast 10K pot V+ & gnd ; 4 - RS RA0 PIC(17) 5 - RW gnd 6 - E RA1 PIC(18) ; 7 - D0 gnd 8 - D1 gnd 9 - D2 gnd 10 - D3 gnd ; 11 - D4 RB0 (6) 12 - D5 RB1 (7) 13 - D6 RB2 (8) 14 - D7 (9) LIST P=16F84 ; 16F84 Runs at 4.096 MHz INCLUDE "p16f84.inc" __CONFIG _PWRTE_ON & _XT_OSC & _WDT_OFF ERRORLEVEL -224 ; supress annoying message from tris ; Define Information #DEFINE RS PORTA, 0 #DEFINE E PORTA, 1 #DEFINE TOGGLESW PORTA, 4 ; Macro EStrobe MACRO ; Strobe the "E" Bit bsf E bcf E ENDM CBLOCK 0CH sec ; seconds digit sec10 ; 10's of second digit mins ; minutes digit min10 ; 10's of minutes digit hr ; hours digit hr10 ; 10's of hours digit highlim ; high limit + 1 of digit w_temp ; holds W during interrupt status_temp ; holds STATUS during interrupt fsr_temp ; holds FSR during interrupt Dlay ; 8 Bit Delay Variable working ; working flag 0 not working, 1 working ptr ; used in displaying message Temp ; a temporary variable bin ; a temporary variable oset ; offset of time register oldtime ; holds last value of sec cntmsec ; used in counting milliseconds isrcnt ; used in isr to stretch time to 1 sec ENDC ORG 0 ; start at location 0 goto main ; jump over to main routine ORG 4 goto isr ; jump to interrupt routine ;----------------------------------------------------------------------; ; High limit + 1 of digits at position W ; ;----------------------------------------------------------------------; sethi: addwf PCL, f dt H'A',H'6',H'A',H'6',H'A',H'A' ;----------------------------------------------------------------------; ; Data for message to be output ; ;----------------------------------------------------------------------; shomsg ; Message to Output addwf PCL, f ; Output the Characters dt "Working Time:", 0 ;----------------------------------------------------------------------; ; ISR, increments time by one second, (BCD), every 125th time through ; ;----------------------------------------------------------------------; isr: movwf w_temp ; save W swapf STATUS,W ; save status movwf status_temp ; without changing flags swapf FSR,W ; save FSR movwf fsr_temp ; without changing flags decfsz isrcnt, f ; count down to zero before incr. goto restore movlw D'125' ; reset isr count movwf isrcnt movf working, f ; check working flag btfsc STATUS, Z ; if not zero then increment time goto restore ; else get out of interrupt routine movlw sec ; point at sec register movwf FSR newdigit: incf INDF, f ; current digit up one movlw sec ; get difference, sec and FSR subwf FSR, W call sethi ; use to get high limit + 1 subwf INDF, W ; reached that number yet? btfss STATUS, Z ; skip over if yes goto restore ; else exit isr clrf INDF ; set current digit to 0 incf FSR, f ; point at next digit goto newdigit ; no, increment the next digit restore: swapf status_temp,W ; get original status back movwf STATUS ; into status register swapf fsr_temp,W ; get original fsr back movwf FSR ; into status register swapf w_temp,f ; old no flags trick again swapf w_temp,W ; to restore W bcf INTCON,T0IF ; clear the TMR0 interrupt flag retfie ; finished reset GIE ;----------------------------------------------------------------------; ; Initialize the ports ; ;----------------------------------------------------------------------; init: clrf PORTA clrf PORTB movlw B'00010000' ; RA4 input, others outputs tris PORTA movlw B'00000000' ; all outputs on port B tris PORTB movlw B'00000011' ; pull-ups enabled ; prescaler assigned to TMR0 ; prescaler set to 1:16 ; rolls over each 125th second option movlw 0 ; zero out all registers movwf hr10 movwf hr movwf min10 movwf mins movwf sec10 movwf sec clrf working ; working flag to zero movlw B'10100000' ; GIE set T0IE set, T0IF cleared movwf INTCON return ;----------------------------------------------------------------------; ; Initialize the LCD ; ;----------------------------------------------------------------------; initlcd: movlw D'40' call nmsec ; Wait 40 msecs before Reset bcf RS ; send an 8 bit instruction movlw 0x03 ; Reset Command call NybbleOut ; Send the Nybble call Dlay5 ; Wait 5 msecs before Sending Again EStrobe call Dlay160 ; Wait 160 usecs before Sending 2nd Time EStrobe call Dlay160 ; Wait 160 usecs before Sending 3rd Time bcf RS ; send an 8 bit instruction movlw 0x02 ; Set 4 Bit Mode call NybbleOut call Dlay160 movlw 0x028 ; 4 bit, 2 Line, 5x7 font call SendINS movlw 0x010 ; display shift off call SendINS movlw 0x001 ; Clear the Display RAM call SendINS call Dlay5 ; Note, Can take up to 4.1 msecs movlw 0x006 ; increment cursor call SendINS movlw 0x00C ; display on cursor off call SendINS return ;----------------------------------------------------------------------; ; Send the character in W out to the LCD ; ;----------------------------------------------------------------------; SendASCII addlw '0' ; Send nbr as ASCII character SendCHAR ; Send the Character to the LCD movwf Temp ; Save the Temporary Value swapf Temp, w ; Send the High Nybble bsf RS ; RS = 1 call NybbleOut movf Temp, w ; Send the Low Nybble bsf RS call NybbleOut return ;----------------------------------------------------------------------; ; Send an instruction in W out to the LCD ; ;----------------------------------------------------------------------; SendINS ; Send the Instruction to the LCD movwf Temp ; Save the Temporary Value swapf Temp, w ; Send the High Nybble bcf RS ; RS = 0 call NybbleOut movf Temp, w ; Send the Low Nybble bcf RS call NybbleOut return ;----------------------------------------------------------------------; ; Send the nibble in W out to the LCD ; ;----------------------------------------------------------------------; NybbleOut ; Send a Nybble to the LCD movwf PORTB EStrobe ; Strobe out the LCD Data call Dlay160 ; delay for 160 usec return ;----------------------------------------------------------------------; ; Output the message on the LCD ; ;----------------------------------------------------------------------; OutMessage: movwf FSR ; Point at first letter OutLoop: movf FSR, w ; Get pointer into W incf FSR, f ; Set up for next letter call shomsg ; Get character to output iorlw 0 ; At the End of the Message? btfsc STATUS, Z ; Skip if not at end return ; Yes - Equal to Zero call SendCHAR ; Output the ASCII Character goto OutLoop ; Get the next character ;----------------------------------------------------------------------; ; Wait until button is released ; ;----------------------------------------------------------------------; waitup: btfss TOGGLESW ; test toggle switch goto $ -1 ; ck again if pressed movlw 20 ; wait 20 msec for debounce call nmsec btfss TOGGLESW ; check again, still up? goto $ -4 ; no start over return ; yes, finished ;----------------------------------------------------------------------; ; time delay routines ; ;----------------------------------------------------------------------; Dlay160: movlw D'41' ; delay about 160 usec micro4 addlw H'FF' ; subtract 1 from 'W' btfss STATUS,Z ; skip when you reach zero goto micro4 ; more loops return Dlay5: movlw 5 ; delay for 5 milliseconds goto $ + 2 msec250: movlw D'250' ; delay for 250 milliseconds ;*** N millisecond delay routine *** nmsec: movwf cntmsec ; delay for N (in W) millisec msecloop: movlw D'254' ; load takes .9765625 microsec call micro4 ; by itself CALL takes ... ; 2 + 253 X 4 + 3 + 2 = 1019 ; 1019 * .977 = 995 microsec nop ; .98 microsec decfsz cntmsec, f ; .98 skip not taken, else 1.95 goto msecloop ; 1.95 here: total ~1000 / loop return ; final time through ~999 to here ; overhead in and out ignored ;----------------------------------------------------------------------; ; Display the Time ; ;----------------------------------------------------------------------; DispTime MOVLW H'C0' ; position at beginning of second line CALL SendINS MOVF hr10, W ; tens of hours CALL SendASCII MOVF hr, W ; hours CALL SendASCII MOVLW ":" CALL SendCHAR MOVF min10, W ; tens of minutes CALL SendASCII MOVF mins, W ; minutes CALL SendASCII MOVLW ":" CALL SendCHAR MOVF sec10, W ; tens of seconds CALL SendASCII MOVF sec, W ; seconds CALL SendASCII RETURN ;----------------------------------------------------------------------; ; Toggle Work Flag ; ;----------------------------------------------------------------------; togglewk: movf working, f ; set zero flag if zero btfss STATUS, Z ; skip if working is zero goto turnoff incf working, f ; set working to 1 call waitup ; wait for button release return turnoff: clrf working ; working set to zero call waitup ; wait for button to be released return ;----------------------------------------------------------------------; ; The Main routine ; ;----------------------------------------------------------------------; main: call init ; initialize ports, set up timer call initlcd ; initialize the LCD movlw 0 ; display 'Working Time:' call OutMessage ckbutton: ; check for a press of the TOGGLE button btfss TOGGLESW ; skip if not pressed call togglewk ; else change the mode of timer movf oldtime, W ; is oldtime the same as sec? subwf sec, W btfsc STATUS, Z ; if not, skip over next instruction goto ckbutton ; else continue checking call DispTime ; sec has changed, display the time movf sec, W ; make sec and oldsec the same movwf oldtime goto ckbutton ; and continue checking end ; Note: You could use 4 mhz crystal and change the isr count to ; 125 * 0.98 = 122 but timing would not be exact. You could also use ; a 4 mhz ceramic resonator, just to see if the program works
file: /Techref/piclist/cheapic/wktim4m.htm, 15KB, , updated: 2005/10/14 13:08, local time: 2024/10/31 18:28,
3.147.36.61:LOG IN ©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/techref/piclist/cheapic/wktim4m.htm"> Pushbutton toggles clock on and off, time on LCD</A> |
Did you find what you needed? |