scmael
Newbie level 6
display keyboard status
Dear friends I need help I have a project that has pic16c74 today it is very difficult to find and too expensive How do I replace the pic16f877 Pinout is the same.
;**************************************************************
; WRITTEN BY HAYSSAM SERHAN *
; COPYRIGHT HOME DESIGNS - 961 9 221737 *
; *
; ADDRESS RAMI SERHAN *
; C/O HAYSSAM SERHAN *
; AMERICAN UNIVERSITY OF BEIRUT *
; P.O.BOX : 11-0236/F6 *
; BEIRUT *
; LEBANON *
; *
; DATE 28.7.97 *
; FILE SAVED AS DISPLAY.ASM *
; FOR PIC16C74 WDT=OFF CP=OFF *
; CLOCK 18.00 MHZ RESONATOR *
;**************************************************************
TITLE "DISPLAY.ASM - RTCLOCK + PC KEYBOARD + LCD + EEPROM + INTERFACE DISPLAY"
LIST P = 16C74
;
;HARDWARE SETUP
; A PORT SETUP
;LCD CONTROL LINES
; RA4 = RS (REGISTER SELECT)
; RA5 = E (ENABLE)
;LCD DATA LINES
; RA < 3 : 0>
; B PORT SETUP
;PC KEYBOARD INTERFACE
;RB0/INT = KEYBOARD CLOCK SIGNAL
;RB1 = KEYBOARD DATA SIGNAL
;DATA SELECTION BOARD
;RB2 = CS0
;RB3 = CS1
;RB4 = CS2
;RB5 = CS3
;RB6 = CS4
;RB7 = CS5
; C PORT SETUP
;RC0 = RTC CONTROL LINES
;RC1 = RTC I/O
;RC2 = RTC CLOCK
; SIGNAL TO THE SHIFT REGISTER
;RC3 = CLK SIGNAL TO THE SHIFT REGISTER
;RC6 = DATA SIGNAL TO THE SHIFT REGISTER
;RC4 = SPARE
;RC5 = SPARE
;RC7 = SPARE
; D PORT SETUP
;DATA OUTPUT TO DISPLAY
; RD < 7 : 0 >
; E PORT SETUP
;EEPROM INTERFACE
;RE0 = SCL
;RE1 = SDA
;RE2 = SPARE
INCLUDE <P16C74.INC>
;
;----------------------------------------------------------------------------
; REGISTER FILE ASSIGNMENT
;----------------------------------------------------------------------------
; PROGRAM HANDLES READING AND WRITING OF DS1302 REAL TIME CLOCK
; REGISTERS. ALSO ALLOWS READ AND WRITE OF A BLOCK OF 31 BYTES
; OF MEMORY TO/FROM THE RTC NON VOLATILE DATA AREA.
; A PORT ASSIGNMENT
LCD_DATA EQU PORTA ;THE LCD DATA IS ON THE LOWER 4-BITS
LCD_DATA_TRIS EQU TRISA ;THE TRIS REGISTER FOR THE LCD DATA
LCD_CNTL EQU PORTA ;TWO CONTROLS LINES
E EQU 5 ; LCD ENABLE CONTROL LINE
RS EQU 4 ; LCD REGISTER SELECT CONTROL LINE
; B PORT ASSIGNMENT
KEYPOR EQU PORTB ; PORTB
RB1 EQU 1
CS0 EQU 2
CS1 EQU 3
CS2 EQU 4
CS3 EQU 5
CS4 EQU 6
CS5 EQU 7
; C PORT ASSIGNMENT
RTCRES EQU 0 ; RTC CONTROL LINES
RTCIO EQU 1 ; RTC I/O
RTCCLK EQU 2 ; RTC CLOCK
ISPCLK EQU 3 ; SERIAL SHIFT REGISTER CLOCK
ISPDAT EQU 6 ; SERIAL SHIFT REGISTER DATA INPUT
; D PORT ASSIGNMENT
DISPDAT EQU PORTD
; E PORT ASSIGNMENT
SCL EQU .0 ; EEROM clock bit
SDA EQU .1 ; EEROM data bit
SDPORT EQU PORTE ; EEROM data port
SCPORT EQU PORTE ; EEROM clock port
SHIFT EQU .1
KEY EQU .2
BEG EQU .6
HI EQU .7
; VARIABLE ASSIGNMENT
GP1 EQU 0x20 ; GENERAL PURPOSE REGISTERS
GP2 EQU GP1+1
FSRCOPY EQU GP2+1 ; COPY OF FSR
SERIAL EQU FSRCOPY+1 ; GP REGISTER FOR SHIFTING ETC.
; ********** REAL TIME CLOCK REGISTER COPY****
RTCD EQU SERIAL+1 ; DAYS
RTCH EQU RTCD+1 ; HOURS
RTCM EQU RTCH+1 ; MINUTES
RTCS EQU RTCM+1 ; SECONDS
WCOPY EQU RTCS+1 ; Copy of W register in interrupt push
SCOPY EQU WCOPY+1 ; Copy of status register in interrupt push
PCOPY EQU SCOPY+1 ; Copy of pclath in interrupt push
FLAG EQU PCOPY+1 ; General purpose flag bits here
KEYVAL EQU FLAG+1 ; Used to form key code
; ********** SERIAL EEPROM REGISTER ***********
COUNT EQU KEYVAL+1
EESER EQU COUNT+1
EEPAGE EQU EESER+1 ; Page number
EEBYTE EQU EEPAGE+1 ; Byte counter
EESTART EQU EEBYTE+1 ; eerom start address in block LOW
EECOUNT EQU EESTART+1 ; Bit count when shifting
FLA EQU EECOUNT+1 ; Misc flag bits
STRCOM EQU FLA+1 ; EEROM page/address pointer
; **************** RTC INTERMEDIATE REGISTER *******
MSDH1 EQU STRCOM+1
LSDH1 EQU MSDH1+1
MSDM1 EQU LSDH1+1
LSDM1 EQU MSDM1+1
MSDS1 EQU LSDM1+1
LSDS1 EQU MSDS1+1
; **************** PC KEYBOARD REGISTER ************
NBITS EQU LSDS1+1
NBYTES EQU NBITS+1
KEYTEMP EQU NBYTES+1
LASTKEY EQU KEYTEMP+1
KEYBUFF EQU LASTKEY+1
FLAG1 EQU KEYBUFF+1
KTMP EQU FLAG1+1
BLL EQU KTMP+1
; ************** RTC GENERAL PURPOSE REGISTER ******
MSD EQU BLL+1 ; TEMP. REGISTER, HOLDS MOST SIGNIFICANT
; DIGIT OF BIN TO BCD CONVERSION
LSD EQU MSD+1 ; TEMPORARY REGISTER, HOLDS LEAST SIGNIFICANT
; DIGIT OF BIN TO BCD CONVERSION
TEMP EQU LSD+1 ; TEMPORARY REGISTER
CHAR EQU TEMP+1 ; TEMPORARY REGISTER,
USD EQU CHAR+1 ;
TSD EQU USD+1 ;
MSDH EQU TSD+1
MSDM EQU MSDH+1
MSDS EQU MSDM+1
LSDH EQU MSDS+1
LSDM EQU LSDH+1
LSDS EQU LSDM+1
;*************** GENERAL PURPOSE REGISTER ***********
EECH EQU LSDS+1 ; eerom start address in block HIGH
STRNUM EQU EECH+1
TTT EQU STRNUM+1
TTTF EQU TTT+1
PPP EQU TTTF+1
TABOFF EQU PPP+1
EECL EQU TABOFF+1 ; eerom start address in block LOW
DISPCON EQU EECL+1
LCDH EQU DISPCON+1
AAA EQU LCDH+1
BBB EQU AAA+1
CCC EQU BBB+1
LL EQU CCC+1
HH EQU LL+1
EL EQU HH+1
EH EQU EL+1
LLL EQU EH+1
INL EQU 0x70
INH EQU INL+1
ILH EQU INH+1
CSHIFT EQU ILH+1
WAY EQU CSHIFT+1
WAY2 EQU WAY+1
COLO EQU WAY2+1
TCOLO EQU COLO+1
IEE EQU TCOLO+1
OTYO EQU IEE+1
TBUFF EQU OTYO+1
CH1 EQU 0xA0
CH2 EQU CH1+1
CH3 EQU CH2+1
CH4 EQU CH3+1
CH5 EQU CH4+1
CH6 EQU CH5+1
CH7 EQU CH6+1
CH8 EQU CH7+1
CH9 EQU CH8+1
CH10 EQU CH9+1
CH11 EQU CH10+1
CH12 EQU CH11+1
CH13 EQU CH12+1
CH14 EQU CH13+1
CH15 EQU CH14+1
CH16 EQU CH15+1
CH17 EQU CH16+1
CH18 EQU CH17+1
CH19 EQU CH18+1
CH20 EQU CH19+1
CH21 EQU CH20+1
CH22 EQU CH21+1
CH23 EQU CH22+1
CH24 EQU CH23+1
CH25 EQU CH24+1
CH26 EQU CH25+1
CH27 EQU CH26+1
CH28 EQU CH27+1
CH29 EQU CH28+1
CH30 EQU CH29+1
CH31 EQU CH30+1
CH32 EQU CH31+1
;
CLKR EQU 100h ; Roll over value for rtc - subtract count
; value from this to preset count down time.
DIV256 EQU b'00000111' ; 256us prescale setting
ROMBASE EQU 0 ; Start of program ROM
;
DEV_FREQ EQU D'28000000' ; DEVICE FREQUENCY IS 20 MHZ
DEV_FREQ2 EQU D'3000000' ; DEVICE FREQUENCY IS 2 MHZ
DB_HI_BYTE EQU (HIGH ((( DEV_FREQ / 4 ) * 1 / D'1000')/ 3 )) + 1
LCD_INIT_DELAY EQU (HIGH ((( DEV_FREQ / 4 ) * D'46' / D'10000')/ 3 )) + 1
LCD_INIT_DELAY2 EQU (HIGH ((( DEV_FREQ2/ 4 ) * D'46' / D'10000')/ 3 )) + 1
;
T1OSO EQU 0 ; THE RC0 / T1OSO / T1CKI
;
RESET_V EQU 0x0000 ; ADDRESS OF RESET VECTOR
ISR_V EQU 0x0004 ; ADDRESS OF INTERRUPT VECTOR
TABLE_ADDR EQU 0x07E0 ; ADRESS WHERE TO START TABLES
TAB_ASC1 EQU 0x067B
TAB_ASC2 EQU 0x0754
;
; LCD MODULE COMMANDS
;
DISP_ON EQU 0x00C ; DISPLAY ON
DISP_ON_C EQU 0x00E ; DISPLAY ON, CURSOR ON
DISP_OFF EQU 0x008 ; DISPLAY OFF
CLR_DISP EQU 0x001 ; CLEAR THE DISPLAY
ENTRY_INC EQU 0x006 ;
ENTRY_INC_S EQU 0x007 ;
ENTRY_DEC EQU 0x004 ;
ENTRY_DEC_S EQU 0x005 ;
DD_RAM_ADDR EQU 0x080 ; LEAST SIGNIFICANT 7-BIT ARE FOR ADDRESS
DD_RAM_UL EQU 0x080 ; UPPER LEFT CONER OF THE DISPLAY
DD_RAM_AD1 EQU 0x08C ;
DD_RAM_AD2 EQU 0x0C0 ;
;----------------------------------------------------------------------------
; Flag bit assignment
;----------------------------------------------------------------------------
; The bits in FLAG are defined here
KEYIN EQU 0 ; Set if a key hit is waiting in KEYMAKE
; CONSTANT ASSIGNMENT
; RTC CHIP (DS1302) - CLOCK COMMAND CONSTANTS.
; THESE ARE WRITTEN TO THE RTC IN RTCWR OR RTCRD.
COMWR EQU B'10001110'
SECWR EQU B'10000000' ; COMMAND TO WRITE THE RTC SECONDS
MINWR EQU B'10000010' ; COMMAND TO WRITE THE RTC MINUTES
HOUWR EQU B'10000100' ; COMMAND TO WRITE THE RTC HOURS
DAYWR EQU B'10001010' ; COMMAND TO WRITE THE RTC DAYS
SECRD EQU B'10000001' ; COMMAND TO READ THE RTC SECONDS
MINRD EQU B'10000011' ; COMMAND TO READ THE RTC MINUTES
HOURD EQU B'10000101' ; COMMAND TO READ THE RTC HOURS
DAYRD EQU B'10001011' ; COMMAND TO READ THE RTC DAYS
; PORT DIRECTION SETTING MAKES RTC DATA LINE OUTPUT/INPUT
RTCDOUT EQU B'00000000' ; RTC DATA LINE OUTPUT
RTCDIN EQU B'00000010' ; RTC DATA LINE INPUT
; PORT DIRECTION SETTING MAKES EEPROM SDA LINE OUTPUT/INPUT
SDAIN EQU b'00000010' ; SDA is input when TRIS carried out
SDAOUT EQU b'00000000' ; SDA is output when TRIS carried out
;---------------------------------------------------------------------------
; EEROM routines
;---------------------------------------------------------------------------
; 24LC65 EEROM handling.
; READEE/WRITEE reads/writes 16 bytes at start of EEFSR ( 60 H ) using
; EERD and EEWR.
; In the idle state outside of eerom routines the SCL line must be
; held low if the data line is shared with other devices.
; Routines READEE/WRITEE call one level of subroutines.
; When EERD and EEWR are called, set up as -
; EESTART - eerom read start low address as 8 bits
; On exit -
; EEBYTE - error status code on exit
; Note that the NOP's may be necessary to slow down the interface to
; some eerom parts.
; EEROM constant - device code and hardware address
EECONT EQU b'10100000' ; 7 bit byte only
; Device code is 1010 for 24LC65B
; in bits 7-4.
; Device hardware address as set by A0,1,2
; is placed in bits 3-1.
; The following ram registers are used and MUST be equated to
; suitable values to give BASE RAM PAGE access during eerom read/write.
; EESER, EEBYTE, EESTART, EECOUNT, STRCOM
; The following value sets the read/write ram start address
EEFSR EQU b'01100000' ; Point at start of ram
;
;----------------------------------------------------------------------------
; Bit assignment
;----------------------------------------------------------------------------
; FLAG bits are defined here
EEREAD EQU 0 ; Set for read on entry to EERDWR
;*********************** MACROS **************************
; BANK0 SELECTS REGISTER FILE BANK 0
BANK0 MACRO
BCF STATUS,RP0 ; SELECT BANK 0
ENDM
; BANK1 SELECTS REGISTER FILE BANK 1
BANK1 MACRO
BSF STATUS,RP0 ; SELECT BANK 1
ENDM
; PAGE0 SELECTS ROM PAGE 0
PAGE0 MACRO
BCF PCLATH,3 ; SELECT ROM PAGE 0
ENDM
; PAGE1 SELECTS ROM PAGE 1
PAGE1 MACRO
BSF PCLATH,3 ; SELECT ROM PAGE 1
ENDM
; RTCCLO SETS THE RTC CLOCK LINE LOW
RTCCLO MACRO
BCF PORTC,RTCCLK
ENDM
; RTCCHI SETS THE RTC CLOCK LINE HIGH
RTCCHI MACRO
BSF PORTC,RTCCLK
ENDM
; RTCDLO SETS THE RTC DATA LINE LOW
RTCDLO MACRO
BCF PORTC,RTCIO
ENDM
; RTCDHI SETS THE RTC DATA LINE HIGH
RTCDHI MACRO
BSF PORTC,RTCIO
ENDM
; RTCRLO SETS THE RTC RESET LINE LOW
RTCRLO MACRO
BCF PORTC,RTCRES
ENDM
; RTCRHI SETS THE RTC RESET LINE HIGH
RTCRHI MACRO
BSF PORTC,RTCRES
ENDM
; RTCIDLE SETS THE RTC INTO THE IDLE STATE
RTCIDLE MACRO
RTCRLO
RTCDLO
RTCCLO
ENDM
;******
; PUSH saves the W, STATUS, PCLATH registers during interrupt
PUSH MACRO
MOVWF WCOPY ; Save on curent bank
SWAPF STATUS,W ; Leave Z bit as is
BANK0 ; Save remainder on bank 0
MOVWF SCOPY
MOVFW PCLATH ; STATUS and W are safe - now save PCLATH
MOVWF PCOPY
ENDM
;******
; PULL restores the W, STATUS,PCLATH registers after a PUSH
PULL MACRO
BANK0 ; Restore from bank 0
MOVFW PCOPY ; Restore PCLATH first
MOVWF PCLATH
SWAPF SCOPY,W ; Restore nibble position of STATUS
MOVWF STATUS
SWAPF WCOPY,F
SWAPF WCOPY,W ; Leave Z bit as is
ENDM
;******
; TSTRTC moves TIMER0 to W reg and sets ZERO status
TSTRTC MACRO
MOVFW TMR0 ; Test for timeout
ENDM
;******
; EEBIT clocks the carry bit to the eerom data line.
EEBIT MACRO
LOCAL EEBIT1,EEBIT2
SKPNC
GOTO EEBIT1
; Carry is clear
BCF SDPORT,SDA
GOTO EEBIT2
; Carry is set
EEBIT1 BSF SDPORT,SDA
; Clock the eerom
EEBIT2 NOP
BSF SCPORT,SCL ; Clock high
NOP
BCF SCPORT,SCL ; Clock low
ENDM
;******
; EEGET clocks the byte (left) into EESER from the eerom. Bit count
; is by a '0' flag in EESER.
; Exit with SCL and SDA low and both as outputs
EEGET MACRO
LOCAL EEGET1
MOVLW b'11111110' ; 8 data bits to be read so flag is 8th bit
MOVWF EESER
MOVLW SDAIN ; SDA is input
BANK1
MOVWF TRISE
BANK0
EEGET1 BSF SCPORT,SCL ; Clock high to get the data bit
CLRC ; Assume data is low for now
BTFSC SDPORT,SDA ; Test SDA bit
SETC ; Data was really high!
RLF EESER ; Carry = data bit to data shifter
BCF SCPORT,SCL ; Clock low after data read
BC EEGET1 ; Bit count flag test - loop until 0 appears
; Byte has been received to EESER, restore bus to outputs
MOVLW SDAOUT ; SDA is output
BANK1
MOVWF TRISE
BANK0
ENDM
;******
; EEPUT clocks the byte (left) in EESER into the eerom. Bit count
; is in EECOUNT.
EEPUT MACRO
LOCAL EEPUT1
EEPUT1 RLF EESER ; Get a data bit
EEBIT ; Carry to EEROM data and clock it
DECFSZ EECOUNT ; Count the bits
GOTO EEPUT1 ; Loop until all bits sent
ENDM
;******
; TABSET sets up the lcd table offset pointer before string output
; starts
TABSET MACRO
MOVLW b'11111111' ; Offset is incremented on each call to
; table - first call must generate zero value
; offset.
MOVWF TABOFF
ENDM
;******
; POINT increments the string pointer offset and adds it to the
; PCL ready for string lookup
POINT MACRO
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT8 increments the string pointer offset and adds it to the
; PLC ready for string lookup. Sets PCLATH to 8
POINT8 MACRO
MOVLW .8
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT9 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 9
POINT9 MACRO
MOVLW .9
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT10 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 10
POINT10 MACRO
MOVLW .10
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT11 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 11
POINT11 MACRO
MOVLW .11
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT12 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 12
POINT12 MACRO
MOVLW .12
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT13 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 13
POINT13 MACRO
MOVLW .13
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT14 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 14
POINT14 MACRO
MOVLW .14
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT15 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 15
POINT15 MACRO
MOVLW .15
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
; RESET ADDRESS. DETERMINE TYPE OF RESET
;
ORG RESET_V ; RESET VECTOR LOCATION
GOTO START ; YES
;
;******
; Interrupt vector - PC keyboard
ORG ISR_V
GOTO INT
;
;************************* SUBROUTINES ****************************
;******
; STRING sends the string with number in W register - to the ram
STRING
MOVWF STRNUM
TABSET ; Xero the offset
PAGE1
CALL DOSTR ; Character from string
PAGE0 ; Restore rom page
RETURN
;******
; STRING2 sends the string with number in W register - to the lcd
STRING2
MOVWF STRNUM
TABSET ; Xero the offset
PAGE1
CALL DOSTR2 ; Character from string
PAGE0 ; Restore rom page
RETURN
INIT_DISPLAY MOVLW DISP_ON_C ; DISPLAY ON , CURSON ON
CALL SEND_CMD ; SEND THIS COMMAND TO DISPLAY MODULE
MOVLW CLR_DISP ; CLEAR THE DISPLAY
CALL SEND_CMD ; SEND THIS COMMAND TO DISPLAY MODULE
MOVLW ENTRY_INC ; SET ENTRY MODE INC., NO SHIFT
CALL SEND_CMD ; SEND THIS COMMAND TO DISPLAY MODULE
RETURN
CLEAR_DISP
MOVLW CLR_DISP ; CLEAR THE DISPLAY
CALL SEND_CMD ; SEND THIS COMMAND TO DISPLAY MODULE
RETURN
;
DISPLAY
MOVLW DD_RAM_AD2 ;
CALL SEND_CMD ;
CALL LOAD_HRS ;NO, DO A NOMAL DISPLAY
CALL LOAD_COLON ;
CALL LOAD_MIN ;
CALL LOAD_COLON ;
CALL LOAD_SEC ;
RETURN
;
;
LOAD_HRS
MOVF MSDH, W ; LOAD THE MSD VALUE INTO THE WREG
CALL NUM_TABLE ; GET THE ASCII CODE
CALL SEND_CHAR ; SEND THIS CHARACTER TO THE DISPLAY
;
MOVF LSDH, W ; LOAD THE LSD VALUE INTO THE WREG
CALL NUM_TABLE ; Get ASCII Code
CALL SEND_CHAR ; Send this Character to the Display
RETURN
;
LOAD_COLON MOVLW ' ' ; ASCII Value for a Blank Space
BTFSC LSDS,0 ; Is it an EVEN or ODD second
ADDLW ':' - ' ' ; Is ODD, Second colon is ON.
; ADD delta offset to ASCII characters
CALL SEND_CHAR ; Send this character to the display
RETURN
;
LOAD_MIN
MOVF MSDM,W ; Load the MSD value into the Wreg
CALL NUM_TABLE ; Get the ASCII Code
CALL SEND_CHAR ; Send this character to the Display
;
MOVF LSDM,W ; Load the LSD value into the Wreg
CALL NUM_TABLE ; Get the ASCII Code
CALL SEND_CHAR ; Send this character to the Display
RETURN
LOAD_SEC
MOVF MSDS,W ; Load the MSD value into the Wreg
CALL NUM_TABLE ; Get the ASCII Code
CALL SEND_CHAR ; Send this character to the Display
;
MOVF LSDS,W ; Load the LSD value into the Wreg
CALL NUM_TABLE ; Get the ASCII Code
CALL SEND_CHAR ; Send this character to the Display
RETURN
;
;*************************************************************************
;* SendChar - Sends character to LCD *
;* This routine splits the character into the upper and lower *
;* nibbles and sends to the LCD, upper nibble first. *
;* The data is transmitted on the PORT <3:0>pins *
;*************************************************************************
SEND_CHAR
MOVWF CHAR ; Character to be sent is in W
CALL LCD_DELAY ; Wait for LCD to be ready
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
SWAPF CHAR,W ;
ANDLW 0x0F ; Get upper nibble
MOVWF LCD_DATA ; Send data to LCD
BSF LCD_CNTL,RS ; Set LCD to data mode
BSF LCD_CNTL,E ; toggle E for LCD
NOP
BCF LCD_CNTL,E
MOVF CHAR,W
ANDLW 0x0F ; Get lower nibble
MOVWF LCD_DATA ; Send data to LCD
BSF LCD_CNTL,RS ; Set LCD to data mode
BSF LCD_CNTL,E ; toggle E for LCD
NOP
BCF LCD_CNTL,E
; BCF LCD_CNTL,RS
RETURN
;***************************************************************
;* sendcmd - sends command to lcd *
;* this routine splits the command into the upper and lower *
;* nibbles and sends them to the lcd, upper nible first. *
;* The data is transmitted on the PORT<3:0> pins *
;***************************************************************
SEND_CMD
MOVWF CHAR ; Character to be send is in W
CALL LCD_DELAY ; Wait for LCD to be ready
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
SWAPF CHAR,W ;
ANDLW 0x0F ; Get upper nibble
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CNTL,RS ; Set LCD to command mode
BSF LCD_CNTL,E ; toggle E for LCD
NOP
BCF LCD_CNTL,E
MOVF CHAR,W
ANDLW 0x0F ; Get lower nibble
MOVWF LCD_DATA ; Send data to LCD
BSF LCD_CNTL,E ; Toggle E for LCD
NOP
BCF LCD_CNTL,E
RETURN
;
; This routine takes the calculated times that the delay loop needs to
; be executed, based on the LCD_INIT_DELAY EQUate that includes the
; frequency of operation. These uses registers before they are needed to
; store the time.
;
LCD_DELAY MOVLW LCD_INIT_DELAY ;
MOVWF USD ; Use MSD and LSD Registers to Initilize LCD
CLRF TSD ;
LOOP2 DECFSZ TSD ; Delay time = MSD * ((3 * 256) + 3) * Tcy
GOTO LOOP2 ;
DECFSZ USD ;
END_LCD_DELAY
GOTO LOOP2 ;
RETURN ;
LCD_DELAY3 MOVLW LCD_INIT_DELAY2;
MOVWF USD ; Use MSD and LSD Registers to Initilize LCD
CLRF TSD ;
LOOP23 DECFSZ TSD ; Delay time = MSD * ((3 * 256) + 3) * Tcy
GOTO LOOP23 ;
DECFSZ USD ;
END_LCD_DELAY3
GOTO LOOP23 ;
RETURN ;
; this is the subroutine for a pc keyboard interrupt
INT PUSH ; Save W, STATUS, PCLATH
MOVLW 0
MOVWF PCLATH ; Allow for call to lookup table
BTFSC INTCON,INTF ; TEST FOR INTERRUPT ON INT/RB0
GOTO KBD
GOTO INTX ; Exit from interrupt
KBD
MOVFW NBITS
SUBLW 0x00
BNZ BIT1_8
BIT0
GOTO BUMP
BIT1_8
MOVFW NBITS
SUBLW 0x09
BZ BIT9
MOVFW NBITS
SUBLW 0x0A
BZ BIT10
CLRC
BTFSC KEYPOR,RB1
SETC
RRF KEYTEMP
GOTO BUMP
BIT9
GOTO BUMP
BIT10
MOVFW KEYTEMP
SUBLW 0x12
BZ TAT
MOVFW KEYTEMP
SUBLW 0x59
BNZ NOTLS
TAT
MOVFW LASTKEY
SUBLW 0xF0
BNZ MAKELS
BCF FLAG1,SHIFT
MOVLW 0x12
MOVWF LASTKEY
GOTO TIDY
MAKELS
BSF FLAG1,SHIFT
MOVLW 0x12
MOVWF LASTKEY
GOTO TIDY
NOTLS
MOVFW KEYTEMP
SUBLW 0x14
BNZ NOTCTRL
NOP
GOTO TIDY
NOTCTRL
MOVFW KEYTEMP
SUBLW 0xF0
BNZ NOTBREAK
MOVFW KEYTEMP
MOVWF LASTKEY
GOTO TIDY
NOTBREAK
MOVFW LASTKEY
SUBLW 0xF0
BNZ NOT_F0
MOVLW 0x00
MOVWF LASTKEY
GOTO TIDY
NOT_F0
MOVFW KEYTEMP
MOVWF LASTKEY
MOVWF KTMP
BTFSC FLAG1,SHIFT
GOTO SHIFTED
UNSHIFTED
CALL ASC1
GOTO SKIP1
SHIFTED
CALL ASC2
SKIP1
NOT0
MOVWF KEYBUFF
BSF FLAG1,KEY
MOVLW 0x01
MOVWF NBYTES
TIDY
MOVLW 0x00
MOVWF NBITS
MOVWF KEYTEMP
GOTO INTDONE
BUMP
INCF NBITS
INTDONE
BCF INTCON,INTF
PULL
RETFIE
; General exit from interrupt
INTX BCF INTCON,RBIF ; Clear interrypt calling flag
BCF INTCON,INTF
BCF PIR1,RCIF
PULL ; Restore W, STATUS and PCLATH
RETFIE
; RTCGET READS THE DS1302 REAL TIME CLOCK DAYS, HOURS, MINS, SECS,
; TO PIC RAM.
RTCGET MOVLW SECRD ; PREPARE TO READ THE RTC SECONDS
MOVWF SERIAL ; SET UP THE COMMAND
CALL RTCRD ; GET THE SECONDS DATA
MOVFW SERIAL
MOVWF RTCS ; SET UP LOCAL COPY OF RTC SECONDS
MOVLW MINRD ; PREPARE TO READ THE RTC MINUTES
MOVWF SERIAL ; SET UP THE COMMAND
CALL RTCRD ; GET THE MINUTES DATA
MOVFW SERIAL
MOVWF RTCM ; SET UP LOCAL COPY OF RTC MINUTES
MOVLW HOURD ; PREPARE TO READ THE RTC HOURS
MOVWF SERIAL ; SET UP THE COMMAND
CALL RTCRD ; GET THE HOURS DATA
MOVFW SERIAL
MOVWF RTCH ; SET UP LOCAL COPY OF RTC HOURS
MOVLW DAYRD ; PREPARE TO READ THE RTC DAYS
MOVWF SERIAL ; SET UP THE COMMAND
CALL RTCRD ; GET THE DAYS DATA
MOVFW SERIAL
MOVWF RTCD ; SET UP LOCAL COPY OF RTC DAYS
RETURN ; EXIT FROM READING NEW TIME FROM RTC
; RTCPUT WRITES THE NEW RTC TIME TO THE DS1302 FROM PIC RAM AND
; RESTARTS THE RTC
RTCPUT
MOVLW COMWR
MOVWF SERIAL
MOVLW B'00000000'
MOVWF GP1
CALL RTCWR
CALL CLKSTOP ; STOP THE CLOCK WHILE WRITING THE NEW HOURS
; AND MINUTES. THIS ZEROES THE SECONDS AND
; ALSO PREVENTS ANY ROLLOVER ERRORS BETWEEN
; WRITING THE NEW HOURS AND MINUTES.
MOVLW DAYWR ; WRITE COMMAND FOR RTC
MOVWF SERIAL ; SET RTC COMMAND TO WRITE NEW HOURS
MOVFW RTCD ; GET THE NEW RTC DAYS
MOVWF GP1 ; SET UP NEW DAYS DATA
CALL RTCWR ; WRITE NEW DAYS TO THE RTC
MOVLW HOUWR ; WRITE COMMAND FOR RTC
MOVWF SERIAL ; SET RTC COMMAND TO WRITE NEW HOURS
MOVFW RTCH ; GET THE NEW RTC HOURS
MOVWF GP1 ; SET UP NEW HOURS DATA
CALL RTCWR ; WRITE NEW HOURS TO THE RTC
MOVLW MINWR ; WRITE TO RTC
MOVWF SERIAL ; SET RTC COMMAND TO WRITE NEW MINUTES
MOVFW RTCM ; GET THE NEW RTC MINUTES
MOVWF GP1 ; SET UP NEW MINUTES DATA
CALL RTCWR ; WRITE NEW MINUTES TO THE RTC
MOVLW SECWR ; WRITE TO RTC
MOVWF SERIAL ; SET RTC COMMAND TO WRITE NEW SECONDS
MOVFW RTCS ; GET THE NEW RTC MINUTES
MOVWF GP1 ; SET UP NEW SECONDS DATA
CALL RTCWR ; WRITE NEW SECONDS TO THE RTC
CALL CLKGO ; RESTART THE RTC
MOVLW COMWR
MOVWF SERIAL
MOVLW B'10000000'
MOVWF GP1
CALL RTCWR
RETURN ; EXIT FROM WRITING NEW TIME TO RTC
; CLKGO STARTS THE RTC CHIP.
CLKGO MOVLW SECRD ; GET THE SECONDS FROM RTC
MOVWF SERIAL
CALL RTCRD ; GET THEM NOW
BCF SERIAL,7 ; TOP BIT CLEAR TO START THE CLOCK
MOVFW SERIAL
MOVWF GP1 ; START THE CLOCK WITH THE SAME TIME
MOVLW SECWR ; WRITE BACK THE SECONDS WITH THE 'RUN' FLAG
MOVWF SERIAL
CALL RTCWR
RETURN
; CLKSTOP STOPS THE RTC CHIP.
CLKSTOP MOVLW SECWR
MOVWF SERIAL
MOVLW 0FFH ; WRITE RTC SECS WITH ALL '1'S TO STOP IT
MOVWF GP1
CALL RTCWR
RETURN
; RTCWR WRITES THE REAL TIME CLOCK CHIP WITH THE COMMAND BYTE IN SERIAL
; AND THE WRITTEN DATA BYTE IN GP1 IN BINARY.
; ASSUMES THAT ON ENTRY RTC RST/ AND SCLK ARE LOW.
; ON EXIT RTC RST/ IS LEFT HIGH AND SCLK IS LEFT LOW READY FOR THE
; READ/WRITE TO TAKE PLACE.
RTCWR
RTCCLO ; RTC CLOCK LINE SHOULD BE LOW WHEN -
RTCRHI ; - RTC RESET LINE GOES HIGH
CALL RTCTX ; COMMAND IN SERIAL TO THE RTC
MOVFW GP1 ; GET THE DATA BYTE -
MOVWF SERIAL ; - AND SET UP THE SHIFTER
CALL RTCTX ; DATA TO RTC
RTCRLO ; DATA HAS BEEN WRITTEN TO THE RTC
RETURN ; EXIT FROM RTC WRITE OF COMMAND PLUS DATA
; RTCRD READS THE REAL TIME CLOCK CHIP WITH THE COMMAND BYTE IN SERIAL
; AND THE READ DATA BYTE RETURNED IN SERIAL IN BCD.
; ASSUMES THAT ON ENTRY RTC RST/ AND SCLK ARE LOW.
; ON EXIT RTC RST/ IS LEFT HIGH AND SCLK IS LEFT LOW READY FOR THE
; READ/WRITE TO TAKE PLACE.
RTCRD RTCCLO ; RTC CLOCK LINE SHOULD BE LOW WHEN -
RTCRHI ; - RTC RESET LINE GOES HIGH
CALL RTCTX ; COMMAND IN SERIAL TO THE RTC
MOVLW RTCDIN ; MAKE THE RTC I/O PORT PIN AN INPUT
BANK1
MOVWF TRISC
BANK0
CALL RTCRX ; DATA FROM RTC
MOVLW RTCDOUT ; MAKE THE RTC I/O PORT PIN AN OUTPUT
BANK1
MOVWF TRISC
BANK0
RTCRLO ; DATA HAS BEEN WRITTEN TO THE RTC
RETURN ; EXIT FROM RTC WRITE OF COMMAND AND READ
; RTCTX TRANSMITS THE DATA OUT OF SERIAL TO THE RTC
; USES GP2 AND SERIAL
RTCTX
LOCAL RTX1,RTX2
MOVLW .8 ; NUMBER OF BITS TO SHIFT
MOVWF GP2
RTX1 RTCDLO ; ASSUME THE DATA BIT WILL BE A '0' FOR NOW
RRF SERIAL ; GET THE DATA BIT
BNC RTX2 ; BRANCH IF THE DATA WAS A '0'
RTCDHI ; DATA BIT WAS A '1' ACTUALLY
RTX2 RTCCHI ; CLOCK THE DATA TO THE RTC
RTCCLO
DECF GP2 ; COUNT BITS AS THEY ARE WRITTEN TO THE RTC
BNZ RTX1 ; LOOP UNTIL ALL SENT TO THE RTC
RETURN
; RTCRX RECEIVES THE DATA FROM THE RTC INTO SERIAL
; USES GP2 AND SERIAL
RTCRX
LOCAL RRX1,RRX2
MOVLW .8 ; NUMBER OF BITS TO SHIFT
MOVWF GP2
RRX1 CLRC ; ASSUME THE DATA BIT WILL BE A '0' FOR NOW
BTFSC PORTC,RTCIO ; READ THE BIT FROM THE RTC
SETC ; THE DATA WAS REALLY A '1'
RRF SERIAL ; SHIFT THE DATA BIT INTO SERIAL
RRX2 RTCCHI ; CLOCK THE DATA TO THE RTC
RTCCLO
DECF GP2 ; COUNT BITS AS THEY ARE WRITTEN TO THE RTC
BNZ RRX1 ; LOOP UNTIL ALL SENT TO THE RTC
RETURN
;
;******
; KEY tests if a keyhit is waiting to be parsed -
; returns key in KEYVAL with CARRY SET
GETKE1
CLRC ; Assume no key for the moment
BTFSS FLAG1,KEY
; No key so exit with the carry clear
RETURN ; Exit from KEY
; Key hit waiting so beep, handle flag and exit carry set
BCF FLAG1,KEY ; Clear flag saying a key hit is waiting
SETC ; Flag to caller that KEYVAL is valid
RETURN ; Exit from TKEY
;******
; BSTART starts off eerom communications from SCL,SDA high inputs.
; Generates start bit - SCL high while SDA goes HIGH/LOW followed by
; the slave address - the read/write bit is NOT sent here.
; Format is -
; BIT 7,6,5,4 Slave address - 1010
; BIT 3,2,1 eerom pager
; ENTRY is with SDA,SDL as inputs and set high.
; EXIT with SDA,SCL low and outputs
BSTART
BSF SDPORT,SDA
NOP
BSF SCPORT,SCL
NOP
BCF SDPORT,SDA ; SDA low with SCL high
; This is a start edge
NOP
BCF SCPORT,SCL ; SCL low
; Form the control byte with page address
MOVLW 0x00
MOVWF EESER
CLRC ; Ready for the shift
RLF EESER ; Page select in bits 3,2,1
MOVLW EECONT ; Get the control byte with ls nibble zero
IORWF EESER ; Set up control byte
MOVLW .7 ; Set bit count
MOVWF EECOUNT
EEPUT
RETURN
;******
; BSTOP ends eerom communications. Generates stop bit - SCL
; high while SDA goes LOW/HIGH. Then drop SCL.
BSTOP
BCF SDPORT,SDA ; SDA low
NOP
BSF SCPORT,SCL ; SCL high
NOP
BSF SDPORT,SDA ; SDA high
NOP
BCF SCPORT,SCL ; SCL low
NOP
RETURN
;******
; GETACK gets the ack from the eerom.
; Turns round SDA line and clocks device - exits with EESER clear
; if ack is seen. Eerom is left with SDA/SCL as outputs and low.
GETACK
MOVLW SDAIN ; SDA is input
BANK1
MOVWF TRISE
BANK0
BSF SCPORT,SCL ; SCL high
NOP ; Need to wait up to 4 us
NOP
CLRF EESER ; Assume ack will be seen!
BTFSC SDPORT,SDA ; Test SDA bit for a LOW ack
COMF EESER ; Ack was not seen
BCF SCPORT,SCL ; SCL low
MOVLW SDAOUT ; SDA is output
BANK1
MOVWF TRISE
BANK0
RETURN
;******
;
; READEE/WRITEE reads/writes 16 bytes of ram with eerom page number
; in EEPAGE and the start address in EESTART.
; EEROM 16 byte read on 16 byte address boundary
READEE
BSF FLA,EEREAD ; Flag reading
GOTO WRITEE1
; EEROM 8 byte write on 8 byte address boundary
WRITEE
BCF FLA,EEREAD ; Flag writing
WRITEE1
MOVWF STRCOM ; Save eerom page/address value
MOVLW .16 ; Read/write 16 bytes
;+++
; Form eerom read start address
EERDWR
MOVWF EEBYTE ; Read/write 16 bytes
MOVFW STRCOM
MOVWF EESTART ; Set eerom start address
; Generate the start bit and the control byte which includes the
; page number
CALL BSTART ; Generate a start and control byte with
; page number (7 bits)
CLRC ; Want to read data but device needs a write
; to accept the word address
EEBIT ; Send the bit to eerom
CALL GETACK ; Check for acknowledge from eerom
BTFSC EESER,0 ; Skip if ack was seen from eerom
GOTO EERDQ ; Error here - ack was not seen
; Set up the start address
MOVFW EECH ; Get the start address
MOVWF EESER ; Shift address from here to eerom
MOVLW 8 ; Set up the bit count
MOVWF EECOUNT
EEPUT ; Clock the address to the eerom
CALL GETACK ; Check for acknowledge from eerom
BTFSC EESER,0 ; Skip if ack was seen from eerom
GOTO EERDQ ; Error here - ack was not seen
MOVFW EESTART ; Get the start addresS
MOVWF EESER ; Shift address from here to eerom
MOVLW 8 ; Set up the bit count
MOVWF EECOUNT
EEPUT ; Clock the address to the eerom
CALL GETACK ; Check for acknowledge from eerom
BTFSC EESER,0 ; Skip if ack was seen from eerom
GOTO EERDQ ; Error here - ack was not seen
; Test if read or write and action (read is flagged '1')
BTFSC FLA,EEREAD ; Skip if writing
;++++
; Read the eerom
GOTO EERD
;******
; Writes bytes from FSR pointed ram to eerom as address in EESTART
; On entry -----
; EEBYTE has the byte count.
; EESTART has the eerom start address.
; fsr points to start of ram area.
; On exit -----
; EESTART is preserved
; EEBYTE is zero unless a bus error occurs when it is set to 1.
; Get a data byte and write to eerom
EEWR MOVFW 0 ; Use FSR to retrieve data byte from ram
MOVWF EESER ; Data to shifter
MOVLW 8 ; Set up the bit count
MOVWF EECOUNT
EEPUT ; Byte to eerom
CALL GETACK ; Check for acknowledge from eerom
BTFSC EESER,0 ; Skip if ack was seen from eerom
GOTO EEWRQ ; Error here - ack was not seen
; Written a byte - test if more bytes to send and action if so
DECF EEBYTE ; Another byte to write?
BZ EEWRX ; Exit if no more bytes to write
INCF FSR ; Move the ram read pointer
GOTO EEWR
; Handle the error state
EEWRQ MOVLW 1
MOVWF EEBYTE ; Flag that a bus error has occured
CALL BSTOP
GOTO EEWRZ1
; All bytes written so terminate the write cycle and wait for eerom
; to be idle.
EEWRX CALL BSTOP ; Send a stop
MOVLW b'00000111' ; Set TMR0 for 1/4 second tick
BANK1
MOVWF OPTION_REG ; and do it
BANK0
MOVLW CLKR-.44 ; 40 gives 11 ms delay
MOVWF TMR0 ; Preset divider
EEWRZ MOVF TMR0,W ; Test for timeout
BNZ EEWRZ ; Loop until timed out
EEWRZ1
RETURN ; Exit back to caller
;******
; EERD reads from the eerom.
; On entry -----
; EEBYTE has the byte count.
; EESTART has the eerom start address.
; On exit -----
; Page 3 has the read data
; EESTART is preserved
; EEBYTE is zero unless a bus error occurs when it is set to 1.
EERD
CALL BSTART ; Generating the start condition again!
SETC ; Reading data so tell eerom
EEBIT ; Send the bit to eerom
CALL GETACK ; Check for acknowledge from eerom
BTFSC EESER,0 ; Skip if ack was seen from eerom
GOTO EERDQ ; Error here - ack was not seen
; Eerom is set up for reading - ack data bytes until 8 are read and
; then a stop is sent and read is terminated
EERDB EEGET ; Get the byte from the eerom --
MOVFW EESER ; -- into this reg!
MOVWF 0 ; -- and save at indirect address
DECF EEBYTE ; Count the bytes read from eerom
BZ EERDX ; Exit from reading when all bytes are read
; Another byte to read so ack and loop
BCF SDPORT,SDA ; SDA low is ACK to eerom
MOVLW b'00000000' ; SDA out:
NOP
BSF SCPORT,SCL ; SCL to clock low for ACK to eerom
NOP ; Send ack for 4 us
BCF SCPORT,SCL ; SCL low
INCF FSR ; Move the ram write pointer
GOTO EERDB ; Loop until data block is read
; Handle the error state
EERDQ MOVLW 1
MOVWF EEBYTE ; Flag that a bus error has occured
GOTO EERDX1 ; Jump and exit
; All bytes read so terminate the read cycle.
EERDX CALL BSTOP ; Stop condition to eerom
; On exit, if flag is set, jump return to string send routine
EERDX1
RETURN ; Exit back to caller
;**********************************************************
AFFDISP
MOVFW AAA
MOVWF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS0
NOP
NOP
BCF PORTB,CS0
INCF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS1
NOP
NOP
BCF PORTB,CS1
MOVFW AAA
ADDLW 0x10
MOVWF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS2
NOP
NOP
BCF PORTB,CS2
INCF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS3
NOP
NOP
BCF PORTB,CS3
MOVFW AAA
ADDLW 0x20
MOVWF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS4
NOP
NOP
BCF PORTB,CS4
INCF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS5
NOP
NOP
BCF PORTB,CS5
CALL LCD_DELAY3
INCF AAA
INCF AAA
RETURN
;**********************************************************
;
ROTAT
MOVFW CSHIFT
MOVWF ILH
REPEAT
CLRC
RLF INL ; THROUGHT CARRY
RLF INH ; THROUGHT CARRY
DECF ILH
BNZ REPEAT
RETURN
ROTAT2
MOVFW CSHIFT
MOVWF ILH
REPEAT2
CLRC
RRF INH ; THROUGHT CARRY
RRF INL ; THROUGHT CARRY
DECF ILH
BNZ REPEAT2
RETURN
;*********************************************************
DTIME
CALL RTCGET
MOVFW RTCH
ANDLW 0x0F
MOVWF LSDH
RRF RTCH
RRF RTCH
RRF RTCH
RRF RTCH
MOVFW RTCH
ANDLW 0x0F
MOVWF MSDH
;
MOVFW RTCM
ANDLW 0x0F
MOVWF LSDM
RRF RTCM
RRF RTCM
RRF RTCM
RRF RTCM
MOVFW RTCM
ANDLW 0x0F
MOVWF MSDM
;
MOVFW RTCS
ANDLW 0x0F
MOVWF LSDS
RRF RTCS
RRF RTCS
RRF RTCS
RRF RTCS
MOVFW RTCS
ANDLW 0x0F
MOVWF MSDS
RETURN
;*********************************************************
RECOR
MOVWF KEYBUFF
MOVLW EEFSR
MOVWF FSR
MOVLW 0x30
SUBWF KEYBUFF,0
CALL STRING
MOVLW EEFSR ; Point at start of read/write ram
MOVWF FSR ; Set up the start pointer
MOVFW EECL ; Get PAGE 1 BLOCK 1 identity
CALL WRITEE ; Write the 16 bytes back from the eerom
MOVFW EECL
ADDLW 0x10
ADDCF EECH
MOVWF EECL
CALL LCD_DELAY
CALL LCD_DELAY
RETURN
; *************************** INIT ***********************
;
;**********************************************************************
;***** Start program here , Power - ON reset occured
;**********************************************************************
;
START ; Power_ON Reset ( Beginning of program)
BANK0 ; Bank 0
CLRF STATUS ; Do Initialization ( Bank 0 )
CLRF INTCON
CLRF PIR1
CLRF T1CON ; RC1 is NOT overridden by TCKO
CLRF NBITS
CLRF KEYTEMP
CLRF KEYBUFF
CLRF FLAG1
CLRF KTMP
CLRF LASTKEY
CLRF EECL
CLRF EECH
MOVLW 0x07
BANK1 ; Bank 1
MOVWF ADCON1
MOVLW 0x80
MOVWF OPTION_REG ;
CLRF PIE1 ; Disable all peripheral interrupts
BANK0 ; Bank 0
CLRF ADCON0
CLRF PORTD ; ALL PORT output should output Low.
CLRF PORTE
CLRF PORTB
CLRF PORTA
BCF SCPORT,SCL
;************** PORT SETUP **************************************
BANK1
; A port setup
MOVLW B'00000000'
MOVWF TRISA
; B port setup
MOVLW b'00000011' ; Set port data directions
MOVWF TRISB
; C PORT SETUP
MOVLW B'00000000' ; SET PORT DATA DIRECTIONS
MOVWF TRISC
; D PORT SETUP
MOVLW B'00000000'
MOVWF TRISD
; E PORT SETUP
MOVLW B'00000000'
MOVWF TRISE
; BSF PIE1,RCIE
BANK0
;******
; Set up timer options
; Timer0 is set for internal, 1/4 ms pre scale
; TIMER1
; TIMER2 is used to debounce the keypad in interrupt ONLY
; It is set for 256 us increment in PR2
MOVLW b'01111111' ; Prescale 16, postscale 16, timer enabled
MOVWF T2CON
; Set miscellaneous flags
CLRF FLAG
;
; Initialize the LCD Display Module
;
CLRF LCD_CNTL ; ALL PORT output should output low.
DISPLAY_INIT
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x03 ; Command for 4-bit interface
MOVWF LCD_DATA ;
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x03 ; Command for 4-bit interface
MOVWF LCD_DATA ;
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x03 ; Command for 4-bit interface
MOVWF LCD_DATA ;
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x02 ; Command for 4-bit interface
MOVWF LCD_DATA ;
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
;
; Command sequence for 2 lines of 5x7 characters
;
CMD_SEQ MOVLW 0x02
MOVWF LCD_DATA
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
MOVLW 0x08 ;
MOVWF LCD_DATA ;
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
;
; Busy Flag should valid after this point
;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW DISP_OFF ;
CALL SEND_CMD ;
MOVLW CLR_DISP ;
CALL SEND_CMD ;
MOVLW ENTRY_INC ;
CALL SEND_CMD ;
MOVLW DISP_ON_C ;
CALL SEND_CMD ;
MOVLW DD_RAM_ADDR ;
CALL SEND_CMD ;
; Global interrupt enable
BCF INTCON,RBIF ; Cancel keypad just in case
BCF INTCON,INTF
BSF INTCON,INTE
BSF INTCON,PEIE
BSF INTCON,GIE ; Enable all Interrupts
RTCIDLE ; IDLE THE CLOCK INTERFACE
; CLEAR THE DISPLAY IN THIS PLACE SO WE HAVE TO SHIFT 32 ZEROS INTO THE
; ispLSI 2032
BCF PORTC,3
NOP
BSF PORTC,6
CLRF DISPCON
CONTI
BSF PORTC,3
NOP
NOP
BCF PORTC,3
INCF DISPCON
BTFSS DISPCON,5
GOTO CONTI
IDLE
MOVLW EEFSR ; Point at start of read/write ram
MOVWF FSR ; Set up the start pointer
; BCF INTCON,GIE ; Enable all Interrupts
CALL CLEAR_DISP ;
CLRF TTTF
CLRF TTT
CLRF LSDS
MOVLW DD_RAM_ADDR
CALL SEND_CMD
MOVLW .11
CALL STRING2
MOVLW .12
CALL STRING2
MOVLW DD_RAM_AD2
CALL SEND_CMD
MOVLW .13
CALL STRING2
MOVLW .14
CALL STRING2
; BSF INTCON,GIE ; Enable all Interrupts
;--------------------------------------------------------------------------
;WAITING LOOP TO SEE IF THE USER WANT TO PROGRAM NEW DATA INTO THE BILLBOARD
;THE LOOP WILL WAIT ABOUT 8 SECONDS ,IF F8 KEY IS NOT PRESSED IN THIS DELAY
;THEN THE BILLBOARD WILL DISPLAY OLD DATA
;---------------------------------------------------------------------------
CLRF OTYO
CLRF TTT
BEGIN
CALL RTCGET ; READ FROM THE REAL TIME CLOCK
BTFSS RTCS,0
GOTO GEN
BTFSC OTYO,0
GOTO TEN
BSF OTYO,0
INCF TTT
BEN
BTFSC TTT,3
GOTO AFF11
GOTO TEN
GEN
BCF OTYO,0
TEN
CALL GETKE1
BNC BEGIN ; Just loop until key found
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x0A ; F8
SUBWF KTMP,W
BZ DRY
MOVLW 0x09 ; F10
SUBWF KTMP,W
BZ AFF11
GOTO BEGIN
DRY
MOVLW 0xA0
MOVWF DISPCON
DATAEN
CLRF IEE
DATAENTRY
; BCF INTCON,GIE ; Enable all Interrupts
CALL CLEAR_DISP
MOVLW DD_RAM_ADDR ;
CALL SEND_CMD
MOVFW IEE
ADDLW 0x01
CALL STRING2
MOVFW IEE
ADDLW 0x02
CALL STRING2
MOVLW DD_RAM_AD2 ;
CALL SEND_CMD
MOVFW IEE
ADDLW 0x03
CALL STRING2
MOVFW IEE
ADDLW 0x04
CALL STRING2
; BSF INTCON,GIE ; Enable all Interrupts
CLRF COLO
DAE
; CALL GETKE1
; BNC DAE ; Just loop until key found
; Key in W register - parse it
; MOVLW 0xE0
; SUBWF KTMP,W
; BNZ DAE2
TRW
CALL GETKE1
BNC TRW ; Just loop until key found
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x75 ;UP
SUBWF KTMP,W
BZ TEW
MOVLW 0x72 ;DOWN
SUBWF KTMP,W
BNZ DAE2
MOVLW 0x0A
SUBWF IEE,W
BZ DAE
INCF IEE
INCF IEE
GOTO DATAENTRY
TEW
MOVLW 0x00
SUBWF IEE,W
BZ DAE
DECF IEE
DECF IEE
GOTO DATAENTRY
DAE2
MOVLW 0x05 ; F1 : SO PROGRAM THE RTCCLOCK WITH NEW TIME
SUBWF KTMP,W ; IN THE FORMAT HHMMSS
BZ PTIME
MOVLW 0x06 ; F2 : PROGRAM THE BILLBOARD WITH DATA THAT IS
SUBWF KTMP,W ; DISPLAYED FROM RIGHT TO LEFT (NOTE:NUMBER OF
BZ PRL ; CHARACTERS MUST BE n*16 IF NOT THE SYSTEM
; WILL COMPLETE IT WITH SPACE)
MOVLW 0x04 ; F3 : PROGRAM THE BILLBOARD WITH DATA THAT IS
SUBWF KTMP,W ; DISPLAYED FROM DOWN TO UP (NOTE:THIS MUST BE
BZ PDU ; A 12 CHARACTERS MESSAGE)
; THIS FUNCTION MAY BE PROGRAMMED MANY TIME AS
; WE WANT
MOVLW 0x0C ; F4 : PROGRAM THE BILLBOARD WITH DATA THAT IS
SUBWF KTMP,W ; DISPLAYED FROM LEFT TO RIGHT LIKE OPENING
BZ PLR ; A CURTAIN ON A MESSAGE(NOTE:THIS MUST BE A 12
; CHARACTERS MESSAGE ALSO)
; THIS FUNCTION MAY BE PROGRAMMED MANY TIME AS
; WE WANT
MOVLW 0x09 ; F10
SUBWF KTMP,W
BZ AFF11
MOVLW 0x03 ; F5 : READ THE REAL TIME CLOCK
SUBWF KTMP,W
BNZ DAE
;***********************************************************************
RRTC
; BCF INTCON,GIE ; Enable all Interrupts
CALL CLEAR_DISP
MOVLW DD_RAM_ADDR ;
CALL SEND_CMD
MOVLW .10
CALL STRING2
; BSF INTCON,GIE ; Enable all Interrupts
BACK
CALL DTIME
CALL DISPLAY
CALL LCD_DELAY
CALL LCD_DELAY
CALL GETKE1
BNC BACK ; Just loop until key found
GOTO DATAENTRY
;***********************************************************************
PLR
; BCF INTCON,GIE ; Enable all Interrupts
CLRF TTT
CALL CLEAR_DISP
MOVLW DD_RAM_ADDR
CALL SEND_CMD
MOVLW .8
CALL STRING2
MOVLW DD_RAM_AD2
CALL SEND_CMD
; BSF INTCON,GIE ; Enable all Interrupts
MOVFW DISPCON
MOVWF FSR
MOVLW 0x02
MOVWF INDF
INCF FSR
MOVFW FSR
MOVWF DISPCON
GOTO WAI
;***********************************************************************
PTIME
; BCF INTCON,GIE ; Enable all Interrupts
CALL CLEAR_DISP
MOVLW DD_RAM_ADDR
CALL SEND_CMD
MOVLW .2
CALL STRING2
MOVLW DD_RAM_AD2
CALL SEND_CMD
; BSF INTCON,GIE ; Enable all Interrupts
ID1
CALL GETKE1
BNC ID1
MOVFW KEYBUFF
CALL SEND_CHAR
MOVFW KEYBUFF
ANDLW 0x0F
MOVWF MSDH
ID2
CALL GETKE1
BNC ID2
Dear friends I need help I have a project that has pic16c74 today it is very difficult to find and too expensive How do I replace the pic16f877 Pinout is the same.
;**************************************************************
; WRITTEN BY HAYSSAM SERHAN *
; COPYRIGHT HOME DESIGNS - 961 9 221737 *
; *
; ADDRESS RAMI SERHAN *
; C/O HAYSSAM SERHAN *
; AMERICAN UNIVERSITY OF BEIRUT *
; P.O.BOX : 11-0236/F6 *
; BEIRUT *
; LEBANON *
; *
; DATE 28.7.97 *
; FILE SAVED AS DISPLAY.ASM *
; FOR PIC16C74 WDT=OFF CP=OFF *
; CLOCK 18.00 MHZ RESONATOR *
;**************************************************************
TITLE "DISPLAY.ASM - RTCLOCK + PC KEYBOARD + LCD + EEPROM + INTERFACE DISPLAY"
LIST P = 16C74
;
;HARDWARE SETUP
; A PORT SETUP
;LCD CONTROL LINES
; RA4 = RS (REGISTER SELECT)
; RA5 = E (ENABLE)
;LCD DATA LINES
; RA < 3 : 0>
; B PORT SETUP
;PC KEYBOARD INTERFACE
;RB0/INT = KEYBOARD CLOCK SIGNAL
;RB1 = KEYBOARD DATA SIGNAL
;DATA SELECTION BOARD
;RB2 = CS0
;RB3 = CS1
;RB4 = CS2
;RB5 = CS3
;RB6 = CS4
;RB7 = CS5
; C PORT SETUP
;RC0 = RTC CONTROL LINES
;RC1 = RTC I/O
;RC2 = RTC CLOCK
; SIGNAL TO THE SHIFT REGISTER
;RC3 = CLK SIGNAL TO THE SHIFT REGISTER
;RC6 = DATA SIGNAL TO THE SHIFT REGISTER
;RC4 = SPARE
;RC5 = SPARE
;RC7 = SPARE
; D PORT SETUP
;DATA OUTPUT TO DISPLAY
; RD < 7 : 0 >
; E PORT SETUP
;EEPROM INTERFACE
;RE0 = SCL
;RE1 = SDA
;RE2 = SPARE
INCLUDE <P16C74.INC>
;
;----------------------------------------------------------------------------
; REGISTER FILE ASSIGNMENT
;----------------------------------------------------------------------------
; PROGRAM HANDLES READING AND WRITING OF DS1302 REAL TIME CLOCK
; REGISTERS. ALSO ALLOWS READ AND WRITE OF A BLOCK OF 31 BYTES
; OF MEMORY TO/FROM THE RTC NON VOLATILE DATA AREA.
; A PORT ASSIGNMENT
LCD_DATA EQU PORTA ;THE LCD DATA IS ON THE LOWER 4-BITS
LCD_DATA_TRIS EQU TRISA ;THE TRIS REGISTER FOR THE LCD DATA
LCD_CNTL EQU PORTA ;TWO CONTROLS LINES
E EQU 5 ; LCD ENABLE CONTROL LINE
RS EQU 4 ; LCD REGISTER SELECT CONTROL LINE
; B PORT ASSIGNMENT
KEYPOR EQU PORTB ; PORTB
RB1 EQU 1
CS0 EQU 2
CS1 EQU 3
CS2 EQU 4
CS3 EQU 5
CS4 EQU 6
CS5 EQU 7
; C PORT ASSIGNMENT
RTCRES EQU 0 ; RTC CONTROL LINES
RTCIO EQU 1 ; RTC I/O
RTCCLK EQU 2 ; RTC CLOCK
ISPCLK EQU 3 ; SERIAL SHIFT REGISTER CLOCK
ISPDAT EQU 6 ; SERIAL SHIFT REGISTER DATA INPUT
; D PORT ASSIGNMENT
DISPDAT EQU PORTD
; E PORT ASSIGNMENT
SCL EQU .0 ; EEROM clock bit
SDA EQU .1 ; EEROM data bit
SDPORT EQU PORTE ; EEROM data port
SCPORT EQU PORTE ; EEROM clock port
SHIFT EQU .1
KEY EQU .2
BEG EQU .6
HI EQU .7
; VARIABLE ASSIGNMENT
GP1 EQU 0x20 ; GENERAL PURPOSE REGISTERS
GP2 EQU GP1+1
FSRCOPY EQU GP2+1 ; COPY OF FSR
SERIAL EQU FSRCOPY+1 ; GP REGISTER FOR SHIFTING ETC.
; ********** REAL TIME CLOCK REGISTER COPY****
RTCD EQU SERIAL+1 ; DAYS
RTCH EQU RTCD+1 ; HOURS
RTCM EQU RTCH+1 ; MINUTES
RTCS EQU RTCM+1 ; SECONDS
WCOPY EQU RTCS+1 ; Copy of W register in interrupt push
SCOPY EQU WCOPY+1 ; Copy of status register in interrupt push
PCOPY EQU SCOPY+1 ; Copy of pclath in interrupt push
FLAG EQU PCOPY+1 ; General purpose flag bits here
KEYVAL EQU FLAG+1 ; Used to form key code
; ********** SERIAL EEPROM REGISTER ***********
COUNT EQU KEYVAL+1
EESER EQU COUNT+1
EEPAGE EQU EESER+1 ; Page number
EEBYTE EQU EEPAGE+1 ; Byte counter
EESTART EQU EEBYTE+1 ; eerom start address in block LOW
EECOUNT EQU EESTART+1 ; Bit count when shifting
FLA EQU EECOUNT+1 ; Misc flag bits
STRCOM EQU FLA+1 ; EEROM page/address pointer
; **************** RTC INTERMEDIATE REGISTER *******
MSDH1 EQU STRCOM+1
LSDH1 EQU MSDH1+1
MSDM1 EQU LSDH1+1
LSDM1 EQU MSDM1+1
MSDS1 EQU LSDM1+1
LSDS1 EQU MSDS1+1
; **************** PC KEYBOARD REGISTER ************
NBITS EQU LSDS1+1
NBYTES EQU NBITS+1
KEYTEMP EQU NBYTES+1
LASTKEY EQU KEYTEMP+1
KEYBUFF EQU LASTKEY+1
FLAG1 EQU KEYBUFF+1
KTMP EQU FLAG1+1
BLL EQU KTMP+1
; ************** RTC GENERAL PURPOSE REGISTER ******
MSD EQU BLL+1 ; TEMP. REGISTER, HOLDS MOST SIGNIFICANT
; DIGIT OF BIN TO BCD CONVERSION
LSD EQU MSD+1 ; TEMPORARY REGISTER, HOLDS LEAST SIGNIFICANT
; DIGIT OF BIN TO BCD CONVERSION
TEMP EQU LSD+1 ; TEMPORARY REGISTER
CHAR EQU TEMP+1 ; TEMPORARY REGISTER,
USD EQU CHAR+1 ;
TSD EQU USD+1 ;
MSDH EQU TSD+1
MSDM EQU MSDH+1
MSDS EQU MSDM+1
LSDH EQU MSDS+1
LSDM EQU LSDH+1
LSDS EQU LSDM+1
;*************** GENERAL PURPOSE REGISTER ***********
EECH EQU LSDS+1 ; eerom start address in block HIGH
STRNUM EQU EECH+1
TTT EQU STRNUM+1
TTTF EQU TTT+1
PPP EQU TTTF+1
TABOFF EQU PPP+1
EECL EQU TABOFF+1 ; eerom start address in block LOW
DISPCON EQU EECL+1
LCDH EQU DISPCON+1
AAA EQU LCDH+1
BBB EQU AAA+1
CCC EQU BBB+1
LL EQU CCC+1
HH EQU LL+1
EL EQU HH+1
EH EQU EL+1
LLL EQU EH+1
INL EQU 0x70
INH EQU INL+1
ILH EQU INH+1
CSHIFT EQU ILH+1
WAY EQU CSHIFT+1
WAY2 EQU WAY+1
COLO EQU WAY2+1
TCOLO EQU COLO+1
IEE EQU TCOLO+1
OTYO EQU IEE+1
TBUFF EQU OTYO+1
CH1 EQU 0xA0
CH2 EQU CH1+1
CH3 EQU CH2+1
CH4 EQU CH3+1
CH5 EQU CH4+1
CH6 EQU CH5+1
CH7 EQU CH6+1
CH8 EQU CH7+1
CH9 EQU CH8+1
CH10 EQU CH9+1
CH11 EQU CH10+1
CH12 EQU CH11+1
CH13 EQU CH12+1
CH14 EQU CH13+1
CH15 EQU CH14+1
CH16 EQU CH15+1
CH17 EQU CH16+1
CH18 EQU CH17+1
CH19 EQU CH18+1
CH20 EQU CH19+1
CH21 EQU CH20+1
CH22 EQU CH21+1
CH23 EQU CH22+1
CH24 EQU CH23+1
CH25 EQU CH24+1
CH26 EQU CH25+1
CH27 EQU CH26+1
CH28 EQU CH27+1
CH29 EQU CH28+1
CH30 EQU CH29+1
CH31 EQU CH30+1
CH32 EQU CH31+1
;
CLKR EQU 100h ; Roll over value for rtc - subtract count
; value from this to preset count down time.
DIV256 EQU b'00000111' ; 256us prescale setting
ROMBASE EQU 0 ; Start of program ROM
;
DEV_FREQ EQU D'28000000' ; DEVICE FREQUENCY IS 20 MHZ
DEV_FREQ2 EQU D'3000000' ; DEVICE FREQUENCY IS 2 MHZ
DB_HI_BYTE EQU (HIGH ((( DEV_FREQ / 4 ) * 1 / D'1000')/ 3 )) + 1
LCD_INIT_DELAY EQU (HIGH ((( DEV_FREQ / 4 ) * D'46' / D'10000')/ 3 )) + 1
LCD_INIT_DELAY2 EQU (HIGH ((( DEV_FREQ2/ 4 ) * D'46' / D'10000')/ 3 )) + 1
;
T1OSO EQU 0 ; THE RC0 / T1OSO / T1CKI
;
RESET_V EQU 0x0000 ; ADDRESS OF RESET VECTOR
ISR_V EQU 0x0004 ; ADDRESS OF INTERRUPT VECTOR
TABLE_ADDR EQU 0x07E0 ; ADRESS WHERE TO START TABLES
TAB_ASC1 EQU 0x067B
TAB_ASC2 EQU 0x0754
;
; LCD MODULE COMMANDS
;
DISP_ON EQU 0x00C ; DISPLAY ON
DISP_ON_C EQU 0x00E ; DISPLAY ON, CURSOR ON
DISP_OFF EQU 0x008 ; DISPLAY OFF
CLR_DISP EQU 0x001 ; CLEAR THE DISPLAY
ENTRY_INC EQU 0x006 ;
ENTRY_INC_S EQU 0x007 ;
ENTRY_DEC EQU 0x004 ;
ENTRY_DEC_S EQU 0x005 ;
DD_RAM_ADDR EQU 0x080 ; LEAST SIGNIFICANT 7-BIT ARE FOR ADDRESS
DD_RAM_UL EQU 0x080 ; UPPER LEFT CONER OF THE DISPLAY
DD_RAM_AD1 EQU 0x08C ;
DD_RAM_AD2 EQU 0x0C0 ;
;----------------------------------------------------------------------------
; Flag bit assignment
;----------------------------------------------------------------------------
; The bits in FLAG are defined here
KEYIN EQU 0 ; Set if a key hit is waiting in KEYMAKE
; CONSTANT ASSIGNMENT
; RTC CHIP (DS1302) - CLOCK COMMAND CONSTANTS.
; THESE ARE WRITTEN TO THE RTC IN RTCWR OR RTCRD.
COMWR EQU B'10001110'
SECWR EQU B'10000000' ; COMMAND TO WRITE THE RTC SECONDS
MINWR EQU B'10000010' ; COMMAND TO WRITE THE RTC MINUTES
HOUWR EQU B'10000100' ; COMMAND TO WRITE THE RTC HOURS
DAYWR EQU B'10001010' ; COMMAND TO WRITE THE RTC DAYS
SECRD EQU B'10000001' ; COMMAND TO READ THE RTC SECONDS
MINRD EQU B'10000011' ; COMMAND TO READ THE RTC MINUTES
HOURD EQU B'10000101' ; COMMAND TO READ THE RTC HOURS
DAYRD EQU B'10001011' ; COMMAND TO READ THE RTC DAYS
; PORT DIRECTION SETTING MAKES RTC DATA LINE OUTPUT/INPUT
RTCDOUT EQU B'00000000' ; RTC DATA LINE OUTPUT
RTCDIN EQU B'00000010' ; RTC DATA LINE INPUT
; PORT DIRECTION SETTING MAKES EEPROM SDA LINE OUTPUT/INPUT
SDAIN EQU b'00000010' ; SDA is input when TRIS carried out
SDAOUT EQU b'00000000' ; SDA is output when TRIS carried out
;---------------------------------------------------------------------------
; EEROM routines
;---------------------------------------------------------------------------
; 24LC65 EEROM handling.
; READEE/WRITEE reads/writes 16 bytes at start of EEFSR ( 60 H ) using
; EERD and EEWR.
; In the idle state outside of eerom routines the SCL line must be
; held low if the data line is shared with other devices.
; Routines READEE/WRITEE call one level of subroutines.
; When EERD and EEWR are called, set up as -
; EESTART - eerom read start low address as 8 bits
; On exit -
; EEBYTE - error status code on exit
; Note that the NOP's may be necessary to slow down the interface to
; some eerom parts.
; EEROM constant - device code and hardware address
EECONT EQU b'10100000' ; 7 bit byte only
; Device code is 1010 for 24LC65B
; in bits 7-4.
; Device hardware address as set by A0,1,2
; is placed in bits 3-1.
; The following ram registers are used and MUST be equated to
; suitable values to give BASE RAM PAGE access during eerom read/write.
; EESER, EEBYTE, EESTART, EECOUNT, STRCOM
; The following value sets the read/write ram start address
EEFSR EQU b'01100000' ; Point at start of ram
;
;----------------------------------------------------------------------------
; Bit assignment
;----------------------------------------------------------------------------
; FLAG bits are defined here
EEREAD EQU 0 ; Set for read on entry to EERDWR
;*********************** MACROS **************************
; BANK0 SELECTS REGISTER FILE BANK 0
BANK0 MACRO
BCF STATUS,RP0 ; SELECT BANK 0
ENDM
; BANK1 SELECTS REGISTER FILE BANK 1
BANK1 MACRO
BSF STATUS,RP0 ; SELECT BANK 1
ENDM
; PAGE0 SELECTS ROM PAGE 0
PAGE0 MACRO
BCF PCLATH,3 ; SELECT ROM PAGE 0
ENDM
; PAGE1 SELECTS ROM PAGE 1
PAGE1 MACRO
BSF PCLATH,3 ; SELECT ROM PAGE 1
ENDM
; RTCCLO SETS THE RTC CLOCK LINE LOW
RTCCLO MACRO
BCF PORTC,RTCCLK
ENDM
; RTCCHI SETS THE RTC CLOCK LINE HIGH
RTCCHI MACRO
BSF PORTC,RTCCLK
ENDM
; RTCDLO SETS THE RTC DATA LINE LOW
RTCDLO MACRO
BCF PORTC,RTCIO
ENDM
; RTCDHI SETS THE RTC DATA LINE HIGH
RTCDHI MACRO
BSF PORTC,RTCIO
ENDM
; RTCRLO SETS THE RTC RESET LINE LOW
RTCRLO MACRO
BCF PORTC,RTCRES
ENDM
; RTCRHI SETS THE RTC RESET LINE HIGH
RTCRHI MACRO
BSF PORTC,RTCRES
ENDM
; RTCIDLE SETS THE RTC INTO THE IDLE STATE
RTCIDLE MACRO
RTCRLO
RTCDLO
RTCCLO
ENDM
;******
; PUSH saves the W, STATUS, PCLATH registers during interrupt
PUSH MACRO
MOVWF WCOPY ; Save on curent bank
SWAPF STATUS,W ; Leave Z bit as is
BANK0 ; Save remainder on bank 0
MOVWF SCOPY
MOVFW PCLATH ; STATUS and W are safe - now save PCLATH
MOVWF PCOPY
ENDM
;******
; PULL restores the W, STATUS,PCLATH registers after a PUSH
PULL MACRO
BANK0 ; Restore from bank 0
MOVFW PCOPY ; Restore PCLATH first
MOVWF PCLATH
SWAPF SCOPY,W ; Restore nibble position of STATUS
MOVWF STATUS
SWAPF WCOPY,F
SWAPF WCOPY,W ; Leave Z bit as is
ENDM
;******
; TSTRTC moves TIMER0 to W reg and sets ZERO status
TSTRTC MACRO
MOVFW TMR0 ; Test for timeout
ENDM
;******
; EEBIT clocks the carry bit to the eerom data line.
EEBIT MACRO
LOCAL EEBIT1,EEBIT2
SKPNC
GOTO EEBIT1
; Carry is clear
BCF SDPORT,SDA
GOTO EEBIT2
; Carry is set
EEBIT1 BSF SDPORT,SDA
; Clock the eerom
EEBIT2 NOP
BSF SCPORT,SCL ; Clock high
NOP
BCF SCPORT,SCL ; Clock low
ENDM
;******
; EEGET clocks the byte (left) into EESER from the eerom. Bit count
; is by a '0' flag in EESER.
; Exit with SCL and SDA low and both as outputs
EEGET MACRO
LOCAL EEGET1
MOVLW b'11111110' ; 8 data bits to be read so flag is 8th bit
MOVWF EESER
MOVLW SDAIN ; SDA is input
BANK1
MOVWF TRISE
BANK0
EEGET1 BSF SCPORT,SCL ; Clock high to get the data bit
CLRC ; Assume data is low for now
BTFSC SDPORT,SDA ; Test SDA bit
SETC ; Data was really high!
RLF EESER ; Carry = data bit to data shifter
BCF SCPORT,SCL ; Clock low after data read
BC EEGET1 ; Bit count flag test - loop until 0 appears
; Byte has been received to EESER, restore bus to outputs
MOVLW SDAOUT ; SDA is output
BANK1
MOVWF TRISE
BANK0
ENDM
;******
; EEPUT clocks the byte (left) in EESER into the eerom. Bit count
; is in EECOUNT.
EEPUT MACRO
LOCAL EEPUT1
EEPUT1 RLF EESER ; Get a data bit
EEBIT ; Carry to EEROM data and clock it
DECFSZ EECOUNT ; Count the bits
GOTO EEPUT1 ; Loop until all bits sent
ENDM
;******
; TABSET sets up the lcd table offset pointer before string output
; starts
TABSET MACRO
MOVLW b'11111111' ; Offset is incremented on each call to
; table - first call must generate zero value
; offset.
MOVWF TABOFF
ENDM
;******
; POINT increments the string pointer offset and adds it to the
; PCL ready for string lookup
POINT MACRO
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT8 increments the string pointer offset and adds it to the
; PLC ready for string lookup. Sets PCLATH to 8
POINT8 MACRO
MOVLW .8
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT9 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 9
POINT9 MACRO
MOVLW .9
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT10 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 10
POINT10 MACRO
MOVLW .10
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT11 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 11
POINT11 MACRO
MOVLW .11
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT12 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 12
POINT12 MACRO
MOVLW .12
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT13 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 13
POINT13 MACRO
MOVLW .13
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT14 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 14
POINT14 MACRO
MOVLW .14
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
;******
; POINT15 increments the string pointer offset and adds it to the
; PCL ready for string lookup. Sets PCLATH to 15
POINT15 MACRO
MOVLW .15
MOVWF PCLATH
INCF TABOFF
MOVFW TABOFF
ADDWF PCL
ENDM
; RESET ADDRESS. DETERMINE TYPE OF RESET
;
ORG RESET_V ; RESET VECTOR LOCATION
GOTO START ; YES
;
;******
; Interrupt vector - PC keyboard
ORG ISR_V
GOTO INT
;
;************************* SUBROUTINES ****************************
;******
; STRING sends the string with number in W register - to the ram
STRING
MOVWF STRNUM
TABSET ; Xero the offset
PAGE1
CALL DOSTR ; Character from string
PAGE0 ; Restore rom page
RETURN
;******
; STRING2 sends the string with number in W register - to the lcd
STRING2
MOVWF STRNUM
TABSET ; Xero the offset
PAGE1
CALL DOSTR2 ; Character from string
PAGE0 ; Restore rom page
RETURN
INIT_DISPLAY MOVLW DISP_ON_C ; DISPLAY ON , CURSON ON
CALL SEND_CMD ; SEND THIS COMMAND TO DISPLAY MODULE
MOVLW CLR_DISP ; CLEAR THE DISPLAY
CALL SEND_CMD ; SEND THIS COMMAND TO DISPLAY MODULE
MOVLW ENTRY_INC ; SET ENTRY MODE INC., NO SHIFT
CALL SEND_CMD ; SEND THIS COMMAND TO DISPLAY MODULE
RETURN
CLEAR_DISP
MOVLW CLR_DISP ; CLEAR THE DISPLAY
CALL SEND_CMD ; SEND THIS COMMAND TO DISPLAY MODULE
RETURN
;
DISPLAY
MOVLW DD_RAM_AD2 ;
CALL SEND_CMD ;
CALL LOAD_HRS ;NO, DO A NOMAL DISPLAY
CALL LOAD_COLON ;
CALL LOAD_MIN ;
CALL LOAD_COLON ;
CALL LOAD_SEC ;
RETURN
;
;
LOAD_HRS
MOVF MSDH, W ; LOAD THE MSD VALUE INTO THE WREG
CALL NUM_TABLE ; GET THE ASCII CODE
CALL SEND_CHAR ; SEND THIS CHARACTER TO THE DISPLAY
;
MOVF LSDH, W ; LOAD THE LSD VALUE INTO THE WREG
CALL NUM_TABLE ; Get ASCII Code
CALL SEND_CHAR ; Send this Character to the Display
RETURN
;
LOAD_COLON MOVLW ' ' ; ASCII Value for a Blank Space
BTFSC LSDS,0 ; Is it an EVEN or ODD second
ADDLW ':' - ' ' ; Is ODD, Second colon is ON.
; ADD delta offset to ASCII characters
CALL SEND_CHAR ; Send this character to the display
RETURN
;
LOAD_MIN
MOVF MSDM,W ; Load the MSD value into the Wreg
CALL NUM_TABLE ; Get the ASCII Code
CALL SEND_CHAR ; Send this character to the Display
;
MOVF LSDM,W ; Load the LSD value into the Wreg
CALL NUM_TABLE ; Get the ASCII Code
CALL SEND_CHAR ; Send this character to the Display
RETURN
LOAD_SEC
MOVF MSDS,W ; Load the MSD value into the Wreg
CALL NUM_TABLE ; Get the ASCII Code
CALL SEND_CHAR ; Send this character to the Display
;
MOVF LSDS,W ; Load the LSD value into the Wreg
CALL NUM_TABLE ; Get the ASCII Code
CALL SEND_CHAR ; Send this character to the Display
RETURN
;
;*************************************************************************
;* SendChar - Sends character to LCD *
;* This routine splits the character into the upper and lower *
;* nibbles and sends to the LCD, upper nibble first. *
;* The data is transmitted on the PORT <3:0>pins *
;*************************************************************************
SEND_CHAR
MOVWF CHAR ; Character to be sent is in W
CALL LCD_DELAY ; Wait for LCD to be ready
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
SWAPF CHAR,W ;
ANDLW 0x0F ; Get upper nibble
MOVWF LCD_DATA ; Send data to LCD
BSF LCD_CNTL,RS ; Set LCD to data mode
BSF LCD_CNTL,E ; toggle E for LCD
NOP
BCF LCD_CNTL,E
MOVF CHAR,W
ANDLW 0x0F ; Get lower nibble
MOVWF LCD_DATA ; Send data to LCD
BSF LCD_CNTL,RS ; Set LCD to data mode
BSF LCD_CNTL,E ; toggle E for LCD
NOP
BCF LCD_CNTL,E
; BCF LCD_CNTL,RS
RETURN
;***************************************************************
;* sendcmd - sends command to lcd *
;* this routine splits the command into the upper and lower *
;* nibbles and sends them to the lcd, upper nible first. *
;* The data is transmitted on the PORT<3:0> pins *
;***************************************************************
SEND_CMD
MOVWF CHAR ; Character to be send is in W
CALL LCD_DELAY ; Wait for LCD to be ready
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
SWAPF CHAR,W ;
ANDLW 0x0F ; Get upper nibble
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CNTL,RS ; Set LCD to command mode
BSF LCD_CNTL,E ; toggle E for LCD
NOP
BCF LCD_CNTL,E
MOVF CHAR,W
ANDLW 0x0F ; Get lower nibble
MOVWF LCD_DATA ; Send data to LCD
BSF LCD_CNTL,E ; Toggle E for LCD
NOP
BCF LCD_CNTL,E
RETURN
;
; This routine takes the calculated times that the delay loop needs to
; be executed, based on the LCD_INIT_DELAY EQUate that includes the
; frequency of operation. These uses registers before they are needed to
; store the time.
;
LCD_DELAY MOVLW LCD_INIT_DELAY ;
MOVWF USD ; Use MSD and LSD Registers to Initilize LCD
CLRF TSD ;
LOOP2 DECFSZ TSD ; Delay time = MSD * ((3 * 256) + 3) * Tcy
GOTO LOOP2 ;
DECFSZ USD ;
END_LCD_DELAY
GOTO LOOP2 ;
RETURN ;
LCD_DELAY3 MOVLW LCD_INIT_DELAY2;
MOVWF USD ; Use MSD and LSD Registers to Initilize LCD
CLRF TSD ;
LOOP23 DECFSZ TSD ; Delay time = MSD * ((3 * 256) + 3) * Tcy
GOTO LOOP23 ;
DECFSZ USD ;
END_LCD_DELAY3
GOTO LOOP23 ;
RETURN ;
; this is the subroutine for a pc keyboard interrupt
INT PUSH ; Save W, STATUS, PCLATH
MOVLW 0
MOVWF PCLATH ; Allow for call to lookup table
BTFSC INTCON,INTF ; TEST FOR INTERRUPT ON INT/RB0
GOTO KBD
GOTO INTX ; Exit from interrupt
KBD
MOVFW NBITS
SUBLW 0x00
BNZ BIT1_8
BIT0
GOTO BUMP
BIT1_8
MOVFW NBITS
SUBLW 0x09
BZ BIT9
MOVFW NBITS
SUBLW 0x0A
BZ BIT10
CLRC
BTFSC KEYPOR,RB1
SETC
RRF KEYTEMP
GOTO BUMP
BIT9
GOTO BUMP
BIT10
MOVFW KEYTEMP
SUBLW 0x12
BZ TAT
MOVFW KEYTEMP
SUBLW 0x59
BNZ NOTLS
TAT
MOVFW LASTKEY
SUBLW 0xF0
BNZ MAKELS
BCF FLAG1,SHIFT
MOVLW 0x12
MOVWF LASTKEY
GOTO TIDY
MAKELS
BSF FLAG1,SHIFT
MOVLW 0x12
MOVWF LASTKEY
GOTO TIDY
NOTLS
MOVFW KEYTEMP
SUBLW 0x14
BNZ NOTCTRL
NOP
GOTO TIDY
NOTCTRL
MOVFW KEYTEMP
SUBLW 0xF0
BNZ NOTBREAK
MOVFW KEYTEMP
MOVWF LASTKEY
GOTO TIDY
NOTBREAK
MOVFW LASTKEY
SUBLW 0xF0
BNZ NOT_F0
MOVLW 0x00
MOVWF LASTKEY
GOTO TIDY
NOT_F0
MOVFW KEYTEMP
MOVWF LASTKEY
MOVWF KTMP
BTFSC FLAG1,SHIFT
GOTO SHIFTED
UNSHIFTED
CALL ASC1
GOTO SKIP1
SHIFTED
CALL ASC2
SKIP1
NOT0
MOVWF KEYBUFF
BSF FLAG1,KEY
MOVLW 0x01
MOVWF NBYTES
TIDY
MOVLW 0x00
MOVWF NBITS
MOVWF KEYTEMP
GOTO INTDONE
BUMP
INCF NBITS
INTDONE
BCF INTCON,INTF
PULL
RETFIE
; General exit from interrupt
INTX BCF INTCON,RBIF ; Clear interrypt calling flag
BCF INTCON,INTF
BCF PIR1,RCIF
PULL ; Restore W, STATUS and PCLATH
RETFIE
; RTCGET READS THE DS1302 REAL TIME CLOCK DAYS, HOURS, MINS, SECS,
; TO PIC RAM.
RTCGET MOVLW SECRD ; PREPARE TO READ THE RTC SECONDS
MOVWF SERIAL ; SET UP THE COMMAND
CALL RTCRD ; GET THE SECONDS DATA
MOVFW SERIAL
MOVWF RTCS ; SET UP LOCAL COPY OF RTC SECONDS
MOVLW MINRD ; PREPARE TO READ THE RTC MINUTES
MOVWF SERIAL ; SET UP THE COMMAND
CALL RTCRD ; GET THE MINUTES DATA
MOVFW SERIAL
MOVWF RTCM ; SET UP LOCAL COPY OF RTC MINUTES
MOVLW HOURD ; PREPARE TO READ THE RTC HOURS
MOVWF SERIAL ; SET UP THE COMMAND
CALL RTCRD ; GET THE HOURS DATA
MOVFW SERIAL
MOVWF RTCH ; SET UP LOCAL COPY OF RTC HOURS
MOVLW DAYRD ; PREPARE TO READ THE RTC DAYS
MOVWF SERIAL ; SET UP THE COMMAND
CALL RTCRD ; GET THE DAYS DATA
MOVFW SERIAL
MOVWF RTCD ; SET UP LOCAL COPY OF RTC DAYS
RETURN ; EXIT FROM READING NEW TIME FROM RTC
; RTCPUT WRITES THE NEW RTC TIME TO THE DS1302 FROM PIC RAM AND
; RESTARTS THE RTC
RTCPUT
MOVLW COMWR
MOVWF SERIAL
MOVLW B'00000000'
MOVWF GP1
CALL RTCWR
CALL CLKSTOP ; STOP THE CLOCK WHILE WRITING THE NEW HOURS
; AND MINUTES. THIS ZEROES THE SECONDS AND
; ALSO PREVENTS ANY ROLLOVER ERRORS BETWEEN
; WRITING THE NEW HOURS AND MINUTES.
MOVLW DAYWR ; WRITE COMMAND FOR RTC
MOVWF SERIAL ; SET RTC COMMAND TO WRITE NEW HOURS
MOVFW RTCD ; GET THE NEW RTC DAYS
MOVWF GP1 ; SET UP NEW DAYS DATA
CALL RTCWR ; WRITE NEW DAYS TO THE RTC
MOVLW HOUWR ; WRITE COMMAND FOR RTC
MOVWF SERIAL ; SET RTC COMMAND TO WRITE NEW HOURS
MOVFW RTCH ; GET THE NEW RTC HOURS
MOVWF GP1 ; SET UP NEW HOURS DATA
CALL RTCWR ; WRITE NEW HOURS TO THE RTC
MOVLW MINWR ; WRITE TO RTC
MOVWF SERIAL ; SET RTC COMMAND TO WRITE NEW MINUTES
MOVFW RTCM ; GET THE NEW RTC MINUTES
MOVWF GP1 ; SET UP NEW MINUTES DATA
CALL RTCWR ; WRITE NEW MINUTES TO THE RTC
MOVLW SECWR ; WRITE TO RTC
MOVWF SERIAL ; SET RTC COMMAND TO WRITE NEW SECONDS
MOVFW RTCS ; GET THE NEW RTC MINUTES
MOVWF GP1 ; SET UP NEW SECONDS DATA
CALL RTCWR ; WRITE NEW SECONDS TO THE RTC
CALL CLKGO ; RESTART THE RTC
MOVLW COMWR
MOVWF SERIAL
MOVLW B'10000000'
MOVWF GP1
CALL RTCWR
RETURN ; EXIT FROM WRITING NEW TIME TO RTC
; CLKGO STARTS THE RTC CHIP.
CLKGO MOVLW SECRD ; GET THE SECONDS FROM RTC
MOVWF SERIAL
CALL RTCRD ; GET THEM NOW
BCF SERIAL,7 ; TOP BIT CLEAR TO START THE CLOCK
MOVFW SERIAL
MOVWF GP1 ; START THE CLOCK WITH THE SAME TIME
MOVLW SECWR ; WRITE BACK THE SECONDS WITH THE 'RUN' FLAG
MOVWF SERIAL
CALL RTCWR
RETURN
; CLKSTOP STOPS THE RTC CHIP.
CLKSTOP MOVLW SECWR
MOVWF SERIAL
MOVLW 0FFH ; WRITE RTC SECS WITH ALL '1'S TO STOP IT
MOVWF GP1
CALL RTCWR
RETURN
; RTCWR WRITES THE REAL TIME CLOCK CHIP WITH THE COMMAND BYTE IN SERIAL
; AND THE WRITTEN DATA BYTE IN GP1 IN BINARY.
; ASSUMES THAT ON ENTRY RTC RST/ AND SCLK ARE LOW.
; ON EXIT RTC RST/ IS LEFT HIGH AND SCLK IS LEFT LOW READY FOR THE
; READ/WRITE TO TAKE PLACE.
RTCWR
RTCCLO ; RTC CLOCK LINE SHOULD BE LOW WHEN -
RTCRHI ; - RTC RESET LINE GOES HIGH
CALL RTCTX ; COMMAND IN SERIAL TO THE RTC
MOVFW GP1 ; GET THE DATA BYTE -
MOVWF SERIAL ; - AND SET UP THE SHIFTER
CALL RTCTX ; DATA TO RTC
RTCRLO ; DATA HAS BEEN WRITTEN TO THE RTC
RETURN ; EXIT FROM RTC WRITE OF COMMAND PLUS DATA
; RTCRD READS THE REAL TIME CLOCK CHIP WITH THE COMMAND BYTE IN SERIAL
; AND THE READ DATA BYTE RETURNED IN SERIAL IN BCD.
; ASSUMES THAT ON ENTRY RTC RST/ AND SCLK ARE LOW.
; ON EXIT RTC RST/ IS LEFT HIGH AND SCLK IS LEFT LOW READY FOR THE
; READ/WRITE TO TAKE PLACE.
RTCRD RTCCLO ; RTC CLOCK LINE SHOULD BE LOW WHEN -
RTCRHI ; - RTC RESET LINE GOES HIGH
CALL RTCTX ; COMMAND IN SERIAL TO THE RTC
MOVLW RTCDIN ; MAKE THE RTC I/O PORT PIN AN INPUT
BANK1
MOVWF TRISC
BANK0
CALL RTCRX ; DATA FROM RTC
MOVLW RTCDOUT ; MAKE THE RTC I/O PORT PIN AN OUTPUT
BANK1
MOVWF TRISC
BANK0
RTCRLO ; DATA HAS BEEN WRITTEN TO THE RTC
RETURN ; EXIT FROM RTC WRITE OF COMMAND AND READ
; RTCTX TRANSMITS THE DATA OUT OF SERIAL TO THE RTC
; USES GP2 AND SERIAL
RTCTX
LOCAL RTX1,RTX2
MOVLW .8 ; NUMBER OF BITS TO SHIFT
MOVWF GP2
RTX1 RTCDLO ; ASSUME THE DATA BIT WILL BE A '0' FOR NOW
RRF SERIAL ; GET THE DATA BIT
BNC RTX2 ; BRANCH IF THE DATA WAS A '0'
RTCDHI ; DATA BIT WAS A '1' ACTUALLY
RTX2 RTCCHI ; CLOCK THE DATA TO THE RTC
RTCCLO
DECF GP2 ; COUNT BITS AS THEY ARE WRITTEN TO THE RTC
BNZ RTX1 ; LOOP UNTIL ALL SENT TO THE RTC
RETURN
; RTCRX RECEIVES THE DATA FROM THE RTC INTO SERIAL
; USES GP2 AND SERIAL
RTCRX
LOCAL RRX1,RRX2
MOVLW .8 ; NUMBER OF BITS TO SHIFT
MOVWF GP2
RRX1 CLRC ; ASSUME THE DATA BIT WILL BE A '0' FOR NOW
BTFSC PORTC,RTCIO ; READ THE BIT FROM THE RTC
SETC ; THE DATA WAS REALLY A '1'
RRF SERIAL ; SHIFT THE DATA BIT INTO SERIAL
RRX2 RTCCHI ; CLOCK THE DATA TO THE RTC
RTCCLO
DECF GP2 ; COUNT BITS AS THEY ARE WRITTEN TO THE RTC
BNZ RRX1 ; LOOP UNTIL ALL SENT TO THE RTC
RETURN
;
;******
; KEY tests if a keyhit is waiting to be parsed -
; returns key in KEYVAL with CARRY SET
GETKE1
CLRC ; Assume no key for the moment
BTFSS FLAG1,KEY
; No key so exit with the carry clear
RETURN ; Exit from KEY
; Key hit waiting so beep, handle flag and exit carry set
BCF FLAG1,KEY ; Clear flag saying a key hit is waiting
SETC ; Flag to caller that KEYVAL is valid
RETURN ; Exit from TKEY
;******
; BSTART starts off eerom communications from SCL,SDA high inputs.
; Generates start bit - SCL high while SDA goes HIGH/LOW followed by
; the slave address - the read/write bit is NOT sent here.
; Format is -
; BIT 7,6,5,4 Slave address - 1010
; BIT 3,2,1 eerom pager
; ENTRY is with SDA,SDL as inputs and set high.
; EXIT with SDA,SCL low and outputs
BSTART
BSF SDPORT,SDA
NOP
BSF SCPORT,SCL
NOP
BCF SDPORT,SDA ; SDA low with SCL high
; This is a start edge
NOP
BCF SCPORT,SCL ; SCL low
; Form the control byte with page address
MOVLW 0x00
MOVWF EESER
CLRC ; Ready for the shift
RLF EESER ; Page select in bits 3,2,1
MOVLW EECONT ; Get the control byte with ls nibble zero
IORWF EESER ; Set up control byte
MOVLW .7 ; Set bit count
MOVWF EECOUNT
EEPUT
RETURN
;******
; BSTOP ends eerom communications. Generates stop bit - SCL
; high while SDA goes LOW/HIGH. Then drop SCL.
BSTOP
BCF SDPORT,SDA ; SDA low
NOP
BSF SCPORT,SCL ; SCL high
NOP
BSF SDPORT,SDA ; SDA high
NOP
BCF SCPORT,SCL ; SCL low
NOP
RETURN
;******
; GETACK gets the ack from the eerom.
; Turns round SDA line and clocks device - exits with EESER clear
; if ack is seen. Eerom is left with SDA/SCL as outputs and low.
GETACK
MOVLW SDAIN ; SDA is input
BANK1
MOVWF TRISE
BANK0
BSF SCPORT,SCL ; SCL high
NOP ; Need to wait up to 4 us
NOP
CLRF EESER ; Assume ack will be seen!
BTFSC SDPORT,SDA ; Test SDA bit for a LOW ack
COMF EESER ; Ack was not seen
BCF SCPORT,SCL ; SCL low
MOVLW SDAOUT ; SDA is output
BANK1
MOVWF TRISE
BANK0
RETURN
;******
;
; READEE/WRITEE reads/writes 16 bytes of ram with eerom page number
; in EEPAGE and the start address in EESTART.
; EEROM 16 byte read on 16 byte address boundary
READEE
BSF FLA,EEREAD ; Flag reading
GOTO WRITEE1
; EEROM 8 byte write on 8 byte address boundary
WRITEE
BCF FLA,EEREAD ; Flag writing
WRITEE1
MOVWF STRCOM ; Save eerom page/address value
MOVLW .16 ; Read/write 16 bytes
;+++
; Form eerom read start address
EERDWR
MOVWF EEBYTE ; Read/write 16 bytes
MOVFW STRCOM
MOVWF EESTART ; Set eerom start address
; Generate the start bit and the control byte which includes the
; page number
CALL BSTART ; Generate a start and control byte with
; page number (7 bits)
CLRC ; Want to read data but device needs a write
; to accept the word address
EEBIT ; Send the bit to eerom
CALL GETACK ; Check for acknowledge from eerom
BTFSC EESER,0 ; Skip if ack was seen from eerom
GOTO EERDQ ; Error here - ack was not seen
; Set up the start address
MOVFW EECH ; Get the start address
MOVWF EESER ; Shift address from here to eerom
MOVLW 8 ; Set up the bit count
MOVWF EECOUNT
EEPUT ; Clock the address to the eerom
CALL GETACK ; Check for acknowledge from eerom
BTFSC EESER,0 ; Skip if ack was seen from eerom
GOTO EERDQ ; Error here - ack was not seen
MOVFW EESTART ; Get the start addresS
MOVWF EESER ; Shift address from here to eerom
MOVLW 8 ; Set up the bit count
MOVWF EECOUNT
EEPUT ; Clock the address to the eerom
CALL GETACK ; Check for acknowledge from eerom
BTFSC EESER,0 ; Skip if ack was seen from eerom
GOTO EERDQ ; Error here - ack was not seen
; Test if read or write and action (read is flagged '1')
BTFSC FLA,EEREAD ; Skip if writing
;++++
; Read the eerom
GOTO EERD
;******
; Writes bytes from FSR pointed ram to eerom as address in EESTART
; On entry -----
; EEBYTE has the byte count.
; EESTART has the eerom start address.
; fsr points to start of ram area.
; On exit -----
; EESTART is preserved
; EEBYTE is zero unless a bus error occurs when it is set to 1.
; Get a data byte and write to eerom
EEWR MOVFW 0 ; Use FSR to retrieve data byte from ram
MOVWF EESER ; Data to shifter
MOVLW 8 ; Set up the bit count
MOVWF EECOUNT
EEPUT ; Byte to eerom
CALL GETACK ; Check for acknowledge from eerom
BTFSC EESER,0 ; Skip if ack was seen from eerom
GOTO EEWRQ ; Error here - ack was not seen
; Written a byte - test if more bytes to send and action if so
DECF EEBYTE ; Another byte to write?
BZ EEWRX ; Exit if no more bytes to write
INCF FSR ; Move the ram read pointer
GOTO EEWR
; Handle the error state
EEWRQ MOVLW 1
MOVWF EEBYTE ; Flag that a bus error has occured
CALL BSTOP
GOTO EEWRZ1
; All bytes written so terminate the write cycle and wait for eerom
; to be idle.
EEWRX CALL BSTOP ; Send a stop
MOVLW b'00000111' ; Set TMR0 for 1/4 second tick
BANK1
MOVWF OPTION_REG ; and do it
BANK0
MOVLW CLKR-.44 ; 40 gives 11 ms delay
MOVWF TMR0 ; Preset divider
EEWRZ MOVF TMR0,W ; Test for timeout
BNZ EEWRZ ; Loop until timed out
EEWRZ1
RETURN ; Exit back to caller
;******
; EERD reads from the eerom.
; On entry -----
; EEBYTE has the byte count.
; EESTART has the eerom start address.
; On exit -----
; Page 3 has the read data
; EESTART is preserved
; EEBYTE is zero unless a bus error occurs when it is set to 1.
EERD
CALL BSTART ; Generating the start condition again!
SETC ; Reading data so tell eerom
EEBIT ; Send the bit to eerom
CALL GETACK ; Check for acknowledge from eerom
BTFSC EESER,0 ; Skip if ack was seen from eerom
GOTO EERDQ ; Error here - ack was not seen
; Eerom is set up for reading - ack data bytes until 8 are read and
; then a stop is sent and read is terminated
EERDB EEGET ; Get the byte from the eerom --
MOVFW EESER ; -- into this reg!
MOVWF 0 ; -- and save at indirect address
DECF EEBYTE ; Count the bytes read from eerom
BZ EERDX ; Exit from reading when all bytes are read
; Another byte to read so ack and loop
BCF SDPORT,SDA ; SDA low is ACK to eerom
MOVLW b'00000000' ; SDA out:
NOP
BSF SCPORT,SCL ; SCL to clock low for ACK to eerom
NOP ; Send ack for 4 us
BCF SCPORT,SCL ; SCL low
INCF FSR ; Move the ram write pointer
GOTO EERDB ; Loop until data block is read
; Handle the error state
EERDQ MOVLW 1
MOVWF EEBYTE ; Flag that a bus error has occured
GOTO EERDX1 ; Jump and exit
; All bytes read so terminate the read cycle.
EERDX CALL BSTOP ; Stop condition to eerom
; On exit, if flag is set, jump return to string send routine
EERDX1
RETURN ; Exit back to caller
;**********************************************************
AFFDISP
MOVFW AAA
MOVWF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS0
NOP
NOP
BCF PORTB,CS0
INCF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS1
NOP
NOP
BCF PORTB,CS1
MOVFW AAA
ADDLW 0x10
MOVWF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS2
NOP
NOP
BCF PORTB,CS2
INCF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS3
NOP
NOP
BCF PORTB,CS3
MOVFW AAA
ADDLW 0x20
MOVWF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS4
NOP
NOP
BCF PORTB,CS4
INCF FSR
MOVFW INDF
MOVWF PORTD
BSF PORTB,CS5
NOP
NOP
BCF PORTB,CS5
CALL LCD_DELAY3
INCF AAA
INCF AAA
RETURN
;**********************************************************
;
ROTAT
MOVFW CSHIFT
MOVWF ILH
REPEAT
CLRC
RLF INL ; THROUGHT CARRY
RLF INH ; THROUGHT CARRY
DECF ILH
BNZ REPEAT
RETURN
ROTAT2
MOVFW CSHIFT
MOVWF ILH
REPEAT2
CLRC
RRF INH ; THROUGHT CARRY
RRF INL ; THROUGHT CARRY
DECF ILH
BNZ REPEAT2
RETURN
;*********************************************************
DTIME
CALL RTCGET
MOVFW RTCH
ANDLW 0x0F
MOVWF LSDH
RRF RTCH
RRF RTCH
RRF RTCH
RRF RTCH
MOVFW RTCH
ANDLW 0x0F
MOVWF MSDH
;
MOVFW RTCM
ANDLW 0x0F
MOVWF LSDM
RRF RTCM
RRF RTCM
RRF RTCM
RRF RTCM
MOVFW RTCM
ANDLW 0x0F
MOVWF MSDM
;
MOVFW RTCS
ANDLW 0x0F
MOVWF LSDS
RRF RTCS
RRF RTCS
RRF RTCS
RRF RTCS
MOVFW RTCS
ANDLW 0x0F
MOVWF MSDS
RETURN
;*********************************************************
RECOR
MOVWF KEYBUFF
MOVLW EEFSR
MOVWF FSR
MOVLW 0x30
SUBWF KEYBUFF,0
CALL STRING
MOVLW EEFSR ; Point at start of read/write ram
MOVWF FSR ; Set up the start pointer
MOVFW EECL ; Get PAGE 1 BLOCK 1 identity
CALL WRITEE ; Write the 16 bytes back from the eerom
MOVFW EECL
ADDLW 0x10
ADDCF EECH
MOVWF EECL
CALL LCD_DELAY
CALL LCD_DELAY
RETURN
; *************************** INIT ***********************
;
;**********************************************************************
;***** Start program here , Power - ON reset occured
;**********************************************************************
;
START ; Power_ON Reset ( Beginning of program)
BANK0 ; Bank 0
CLRF STATUS ; Do Initialization ( Bank 0 )
CLRF INTCON
CLRF PIR1
CLRF T1CON ; RC1 is NOT overridden by TCKO
CLRF NBITS
CLRF KEYTEMP
CLRF KEYBUFF
CLRF FLAG1
CLRF KTMP
CLRF LASTKEY
CLRF EECL
CLRF EECH
MOVLW 0x07
BANK1 ; Bank 1
MOVWF ADCON1
MOVLW 0x80
MOVWF OPTION_REG ;
CLRF PIE1 ; Disable all peripheral interrupts
BANK0 ; Bank 0
CLRF ADCON0
CLRF PORTD ; ALL PORT output should output Low.
CLRF PORTE
CLRF PORTB
CLRF PORTA
BCF SCPORT,SCL
;************** PORT SETUP **************************************
BANK1
; A port setup
MOVLW B'00000000'
MOVWF TRISA
; B port setup
MOVLW b'00000011' ; Set port data directions
MOVWF TRISB
; C PORT SETUP
MOVLW B'00000000' ; SET PORT DATA DIRECTIONS
MOVWF TRISC
; D PORT SETUP
MOVLW B'00000000'
MOVWF TRISD
; E PORT SETUP
MOVLW B'00000000'
MOVWF TRISE
; BSF PIE1,RCIE
BANK0
;******
; Set up timer options
; Timer0 is set for internal, 1/4 ms pre scale
; TIMER1
; TIMER2 is used to debounce the keypad in interrupt ONLY
; It is set for 256 us increment in PR2
MOVLW b'01111111' ; Prescale 16, postscale 16, timer enabled
MOVWF T2CON
; Set miscellaneous flags
CLRF FLAG
;
; Initialize the LCD Display Module
;
CLRF LCD_CNTL ; ALL PORT output should output low.
DISPLAY_INIT
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x03 ; Command for 4-bit interface
MOVWF LCD_DATA ;
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x03 ; Command for 4-bit interface
MOVWF LCD_DATA ;
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x03 ; Command for 4-bit interface
MOVWF LCD_DATA ;
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x02 ; Command for 4-bit interface
MOVWF LCD_DATA ;
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
;
; Command sequence for 2 lines of 5x7 characters
;
CMD_SEQ MOVLW 0x02
MOVWF LCD_DATA
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
MOVLW 0x08 ;
MOVWF LCD_DATA ;
BSF LCD_CNTL,E ;
NOP
NOP
BCF LCD_CNTL,E ;
;
; Busy Flag should valid after this point
;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW DISP_OFF ;
CALL SEND_CMD ;
MOVLW CLR_DISP ;
CALL SEND_CMD ;
MOVLW ENTRY_INC ;
CALL SEND_CMD ;
MOVLW DISP_ON_C ;
CALL SEND_CMD ;
MOVLW DD_RAM_ADDR ;
CALL SEND_CMD ;
; Global interrupt enable
BCF INTCON,RBIF ; Cancel keypad just in case
BCF INTCON,INTF
BSF INTCON,INTE
BSF INTCON,PEIE
BSF INTCON,GIE ; Enable all Interrupts
RTCIDLE ; IDLE THE CLOCK INTERFACE
; CLEAR THE DISPLAY IN THIS PLACE SO WE HAVE TO SHIFT 32 ZEROS INTO THE
; ispLSI 2032
BCF PORTC,3
NOP
BSF PORTC,6
CLRF DISPCON
CONTI
BSF PORTC,3
NOP
NOP
BCF PORTC,3
INCF DISPCON
BTFSS DISPCON,5
GOTO CONTI
IDLE
MOVLW EEFSR ; Point at start of read/write ram
MOVWF FSR ; Set up the start pointer
; BCF INTCON,GIE ; Enable all Interrupts
CALL CLEAR_DISP ;
CLRF TTTF
CLRF TTT
CLRF LSDS
MOVLW DD_RAM_ADDR
CALL SEND_CMD
MOVLW .11
CALL STRING2
MOVLW .12
CALL STRING2
MOVLW DD_RAM_AD2
CALL SEND_CMD
MOVLW .13
CALL STRING2
MOVLW .14
CALL STRING2
; BSF INTCON,GIE ; Enable all Interrupts
;--------------------------------------------------------------------------
;WAITING LOOP TO SEE IF THE USER WANT TO PROGRAM NEW DATA INTO THE BILLBOARD
;THE LOOP WILL WAIT ABOUT 8 SECONDS ,IF F8 KEY IS NOT PRESSED IN THIS DELAY
;THEN THE BILLBOARD WILL DISPLAY OLD DATA
;---------------------------------------------------------------------------
CLRF OTYO
CLRF TTT
BEGIN
CALL RTCGET ; READ FROM THE REAL TIME CLOCK
BTFSS RTCS,0
GOTO GEN
BTFSC OTYO,0
GOTO TEN
BSF OTYO,0
INCF TTT
BEN
BTFSC TTT,3
GOTO AFF11
GOTO TEN
GEN
BCF OTYO,0
TEN
CALL GETKE1
BNC BEGIN ; Just loop until key found
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x0A ; F8
SUBWF KTMP,W
BZ DRY
MOVLW 0x09 ; F10
SUBWF KTMP,W
BZ AFF11
GOTO BEGIN
DRY
MOVLW 0xA0
MOVWF DISPCON
DATAEN
CLRF IEE
DATAENTRY
; BCF INTCON,GIE ; Enable all Interrupts
CALL CLEAR_DISP
MOVLW DD_RAM_ADDR ;
CALL SEND_CMD
MOVFW IEE
ADDLW 0x01
CALL STRING2
MOVFW IEE
ADDLW 0x02
CALL STRING2
MOVLW DD_RAM_AD2 ;
CALL SEND_CMD
MOVFW IEE
ADDLW 0x03
CALL STRING2
MOVFW IEE
ADDLW 0x04
CALL STRING2
; BSF INTCON,GIE ; Enable all Interrupts
CLRF COLO
DAE
; CALL GETKE1
; BNC DAE ; Just loop until key found
; Key in W register - parse it
; MOVLW 0xE0
; SUBWF KTMP,W
; BNZ DAE2
TRW
CALL GETKE1
BNC TRW ; Just loop until key found
CALL LCD_DELAY ;
CALL LCD_DELAY ;
MOVLW 0x75 ;UP
SUBWF KTMP,W
BZ TEW
MOVLW 0x72 ;DOWN
SUBWF KTMP,W
BNZ DAE2
MOVLW 0x0A
SUBWF IEE,W
BZ DAE
INCF IEE
INCF IEE
GOTO DATAENTRY
TEW
MOVLW 0x00
SUBWF IEE,W
BZ DAE
DECF IEE
DECF IEE
GOTO DATAENTRY
DAE2
MOVLW 0x05 ; F1 : SO PROGRAM THE RTCCLOCK WITH NEW TIME
SUBWF KTMP,W ; IN THE FORMAT HHMMSS
BZ PTIME
MOVLW 0x06 ; F2 : PROGRAM THE BILLBOARD WITH DATA THAT IS
SUBWF KTMP,W ; DISPLAYED FROM RIGHT TO LEFT (NOTE:NUMBER OF
BZ PRL ; CHARACTERS MUST BE n*16 IF NOT THE SYSTEM
; WILL COMPLETE IT WITH SPACE)
MOVLW 0x04 ; F3 : PROGRAM THE BILLBOARD WITH DATA THAT IS
SUBWF KTMP,W ; DISPLAYED FROM DOWN TO UP (NOTE:THIS MUST BE
BZ PDU ; A 12 CHARACTERS MESSAGE)
; THIS FUNCTION MAY BE PROGRAMMED MANY TIME AS
; WE WANT
MOVLW 0x0C ; F4 : PROGRAM THE BILLBOARD WITH DATA THAT IS
SUBWF KTMP,W ; DISPLAYED FROM LEFT TO RIGHT LIKE OPENING
BZ PLR ; A CURTAIN ON A MESSAGE(NOTE:THIS MUST BE A 12
; CHARACTERS MESSAGE ALSO)
; THIS FUNCTION MAY BE PROGRAMMED MANY TIME AS
; WE WANT
MOVLW 0x09 ; F10
SUBWF KTMP,W
BZ AFF11
MOVLW 0x03 ; F5 : READ THE REAL TIME CLOCK
SUBWF KTMP,W
BNZ DAE
;***********************************************************************
RRTC
; BCF INTCON,GIE ; Enable all Interrupts
CALL CLEAR_DISP
MOVLW DD_RAM_ADDR ;
CALL SEND_CMD
MOVLW .10
CALL STRING2
; BSF INTCON,GIE ; Enable all Interrupts
BACK
CALL DTIME
CALL DISPLAY
CALL LCD_DELAY
CALL LCD_DELAY
CALL GETKE1
BNC BACK ; Just loop until key found
GOTO DATAENTRY
;***********************************************************************
PLR
; BCF INTCON,GIE ; Enable all Interrupts
CLRF TTT
CALL CLEAR_DISP
MOVLW DD_RAM_ADDR
CALL SEND_CMD
MOVLW .8
CALL STRING2
MOVLW DD_RAM_AD2
CALL SEND_CMD
; BSF INTCON,GIE ; Enable all Interrupts
MOVFW DISPCON
MOVWF FSR
MOVLW 0x02
MOVWF INDF
INCF FSR
MOVFW FSR
MOVWF DISPCON
GOTO WAI
;***********************************************************************
PTIME
; BCF INTCON,GIE ; Enable all Interrupts
CALL CLEAR_DISP
MOVLW DD_RAM_ADDR
CALL SEND_CMD
MOVLW .2
CALL STRING2
MOVLW DD_RAM_AD2
CALL SEND_CMD
; BSF INTCON,GIE ; Enable all Interrupts
ID1
CALL GETKE1
BNC ID1
MOVFW KEYBUFF
CALL SEND_CHAR
MOVFW KEYBUFF
ANDLW 0x0F
MOVWF MSDH
ID2
CALL GETKE1
BNC ID2