;******************************************************************************* ;** ;** A Simple Clock using LCD ;** ;** Written by Rick Huang, Copyright (C) 2003 ;** Revision 1. Aug 8, 2003 ;** Revision 2. Aug 9, 2003 ;** Revision 3. Aug 30, 2003 ;** ;** This program is free software; you can redistribute it and/or modify ;** it under the terms of the GNU General Public License as published by ;** the Free Software Foundation; either version 2 of the License, or ;** (at your option) any later version. ;** ;** This program is distributed in the hope that it will be useful, ;** but WITHOUT ANY WARRANTY; without even the implied warranty of ;** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;** GNU General Public License for more details. ;** ;** You should have received a copy of the GNU General Public License ;** along with this program; if not, write to the Free Software ;** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ;******************************************************************************* include __config _LP_OSC & _WDT_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_OFF ;***************************************************************** ;** Variables Counter1 EQU 20h Counter2 EQU 21h TempW EQU 22h LastState EQU 23h Digit1 EQU 24h Digit2 EQU 25h Digit3 EQU 26h Compare EQU 27h TempD EQU 28h TempE EQU 29h TempD2 EQU 2ah TempE2 EQU 2bh Second EQU 2ch TeDigit EQU 2dh TeDigit2 EQU 2eh TeDigitL EQU 2fh TeDigitL2 EQU 30h Blink EQU 31h SetCount EQU 32h goto start ORG 4 ;waiting for <0004> ;interrupt vector Int: goto Interrupt ORG 5 ;******************************* Digit table Dig1TableU: addwf PCL, F retlw 007h ;Digit 0 retlw 001h ;1 retlw 003h ;2 retlw 003h ;3 retlw 005h ;4 retlw 006h ;5 retlw 006h ;6 retlw 003h ;7 retlw 007h ;8 retlw 007h ;Digit 9 Dig1TableL: addwf PCL, F retlw 045h ;Digit 0 retlw 001h retlw 046h retlw 043h retlw 003h retlw 043h retlw 047h retlw 001h retlw 047h retlw 003h ;Digit 9 Dig2TableU: addwf PCL, F retlw 038h ;Digit 0 retlw 008h ;1 retlw 018h ;2 retlw 018h ;3 retlw 028h ;4 retlw 030h ;5 retlw 030h ;6 Dig2TableL: addwf PCL, F retlw 028h ;Digit 0 retlw 008h retlw 030h retlw 018h retlw 018h retlw 018h retlw 038h Dig3TableU: addwf PCL, F retlw 083h ;Digit 0 retlw 080h ;1 retlw 081h ;2 retlw 081h ;3 retlw 082h ;4 retlw 003h ;5 retlw 003h ;6 retlw 081h ;7 retlw 083h ;8 retlw 083h ;Digit 9 retlw 087h ;10 retlw 084h ;11 retlw 085h ;12 Dig3TableL: addwf PCL, F retlw 086h ;Digit 0 retlw 080h ;1 retlw 007h ;2 retlw 085h ;3 retlw 081h ;4 retlw 085h ;5 retlw 087h ;6 retlw 080h ;7 retlw 087h ;8 retlw 081h ;Digit 9 retlw 086h ;10 retlw 080h ;11 retlw 007h ;12 ;******************************* Program starting point start: bsf STATUS, RP0 movlw 0x00 movwf TRISB ;Set both port to output movlw b'00100000' ;RA5/MCLR - Clock Set movwf TRISA clrwdt clrf TMR0 movlw b'10000100' ;No prescaler movwf OPTION_REG movlw d'64' movwf PR2 bsf PIE1, TMR2IE bcf STATUS, RP0 movlw b'00000100' ;TMR2 - No pre/postscaler movwf T2CON clrf LastState bsf INTCON, T0IE ;Enable interrupt bsf INTCON, PEIE bcf INTCON, T0IF bsf INTCON, GIE ;Don't enable interrupt at this point ;********************** Disable 16f628 specific features movlw b'00000111' movwf CMCON ;********************** clrf Second clrf Blink clrf Digit1 clrf Digit2 movlw d'12' movwf Digit3 ;12:00 to start clrf Counter2 clrf Compare incf Compare, F StopProgram: call DecodeDisplay goto StopProgram ;******************************* Subroutine DecodeDisplay: movfw Digit1 call Dig1TableU movwf TempD movfw Digit1 call Dig1TableL movwf TempD2 ;----------------- movfw Digit2 call Dig2TableU iorwf TempD, F movfw Digit2 call Dig2TableL iorwf TempD2, F ;----------------- movfw Digit3 call Dig3TableU movwf TempE btfsc TempE, 7 bsf TempD, 7 comf TempD, W movwf TeDigit comf TempE, W andlw 0x07 movwf TeDigit2 ;------------------ movfw Digit3 call Dig3TableL movwf TempE2 btfsc TempE2, 7 bsf TempD2, 7 comf TempD2, W movwf TeDigitL comf TempE2, W andlw 0x07 movwf TeDigitL2 return Interrupt: btfsc INTCON, T0IF goto ClockInc movwf TempW movfw LastState addwf PCL goto UPos ;Check which cycle is on goto UNeg goto LPos goto LNeg ;*********************** UPos UPos: movfw TeDigit xorwf Blink, W movwf PORTB movfw TeDigit2 movwf PORTA bsf PORTA, 3 bsf PORTA, 4 goto DoneDraw UNeg: comf TeDigit, W iorwf Blink, W movwf PORTB comf TeDigit2, W movwf PORTA bcf PORTA, 3 bcf PORTA, 4 goto DoneDraw LPos: movfw TeDigitL movwf TRISB movfw TeDigitL2 movwf TRISA bsf PORTA, 3 bcf PORTA, 4 goto DoneDraw LNeg: comf TeDigitL, W movwf TRISB comf TeDigitL2, W movwf TRISA bcf PORTA, 3 bsf PORTA, 4 goto DoneDraw DoneDraw: incf LastState, F btfsc LastState, 2 clrf LastState bcf PIR1, TMR2IF movfw TempW retfie ;******************* Timer interrupt handeler ClockInc: movwf TempW btfsc PORTA, 5 goto NormalClk ; Increase clock incf SetCount, F btfsc SetCount, 3 goto Check2 goto Check1 NormalClk: clrf SetCount incf Second movlw d'60' xorwf Second, W btfss STATUS, Z goto ExitClock clrf Second Check1: incf Digit1, F movlw 0x0a ; 10 xorwf Digit1, W btfss STATUS, Z goto ExitClock clrf Digit1 incf Digit2, F movlw 0x06 ; 6 xorwf Digit2, W btfss STATUS, Z goto ExitClock clrf Digit2 Check2: incf Digit3, F movlw 0x0d ; 13 xorwf Digit3, W btfss STATUS, Z goto ExitClock clrf Digit3 incf Digit3 ExitClock: movlw b'01000000' xorwf Blink, F bcf INTCON, T0IF movfw TempW retfie ;return ExitInc: return end