list p=PIC16F877A,r=dec include P16F877A.inc include macros.asm ERRORLEVEL -302 __CONFIG H'3F31' #DEFINE PAGE0 BCF H'03',5 ;STATUS bit 5 #DEFINE PAGE1 BSF H'03',5 ;STATUS bit 5 INDF EQU H'00' ;page 0, 1, 2, 3 PCL EQU H'02' ;page 0, 1, 2, 3 STATUS EQU H'03' ;page 0, 1, 2, 3 FSR EQU H'04' ;page 0, 1, 2, 3 LOOPB EQU H'20' ; general loop LOOPC EQU H'21' ; general loop LOOPD EQU H'22' ; general loop LOOPE EQU H'23' ; general loop STORE1 EQU H'24' ; temp store TEMPA EQU H'25' ; temp store CLKCNT EQU H'26' ; counter for PAUSE val ADRLSB EQU H'27' ; low address ADRMSB EQU H'28' ; high address ATTRIB EQU H'29' ; ATTRIBUTE value BITVAL EQU H'2A' ; val of bit to be set/reset RDBYTE EQU H'2B' ; byte read from screen COUNT EQU H'2C' ; counter for BIRD loop, used also for waveform COLUMN EQU H'2D' ; column length holder QCKCOL EQU H'2E' ; quack bill column PEAKLO EQU H'2F' ; waveform peak lo (demo 11) PEAKHI EQU H'30' ; waveform peak hi (demo 11) LOBIT EQU H'31' ; waveform section (demo 11) LOOPLO EQU H'32' ; waveform section (demo 11) JOIN00 EQU H'34' ; 1st store for BIRD roll-over join (right-hand edge bit) ; extends to $50 for JOIN32, used also for waveforms ; (64 for scope style) ;........FIXED VALUES FOR COMMANDS COUNT3 EQU H'35' COUNT2 EQU H'36' BYTE EQU H'37' D1 EQU H'38' D2 EQU H'39' DEL EQU H'40' Bit_Cntr EQU H'41' ;bit counter for RS232 Xmit_Byte EQU H'42' ;holds byte to xmit Rcv_Byte EQU H'43' ;holds received byte Delay_Count EQU H'44' Count2 EQU H'45' byte1 EQU H'46' byte2 EQU H'47' byte3 EQU H'48' byte4 EQU H'49' _N EQU H'50' OutputByte EQU H'51' SDA EQU 6 SCL EQU 7 LOOP1 EQU H'52' LOOP2 EQU H'53' Data_Buf EQU H'54' ADDR1 EQU H'55' ADDR2 EQU H'56' READXCHARS EQU H'57' BX EQU H'58' BY EQU H'59' PX EQU H'60' PY EQU H'61' Ser_Out EQU 0 ;bit position for RS232 out Ser_In EQU 1 ;bit position for RS232 in TXHOME EQU H'40' ; text home address command TXAREA EQU H'41' ; text area (columns) address command GRHOME EQU H'42' ; graphics home address command GRAREA EQU H'43' ; graphic area (columns) address command AWRON EQU H'B0' ; autowrite on command AWROFF EQU H'B2' ; autowrite off command OFFSET EQU H'22' ; offset command ADPSET EQU H'24' ; address set command PEEK EQU H'E0' ; screen peek command CSRPOS EQU H'21' ; set cursor position ommand ;........BIT VALUES W EQU 0 ; working reg F EQU 1 ; file reg Z EQU 2 ; zero status C EQU 0 ; CARRY status RP0 EQU 5 ; STATUS bank reg RP1 EQU 6 ; STATUS bank reg RD EQU 0 ; EEPROM read flag EEPGD EQU 7 ; EECON1 reg FS EQU B'00000000' ;FS mode set by bit 5: 1 = 6x8, 0 = 8x8 ;8x8 needed for EPE demos ;.......... ORG H'04' goto 5 ORG H'05' bcf STATUS,RP0 bcf STATUS,RP1 clrf PORTA clrf PORTB movlw B'01001111' ; FS low, RST low, CD CE RD WR high movwf PORTC clrf PORTD clrf PORTE PAGE1 movlw B'11111110' movwf TRISA ; PORTA as input clrf TRISB ; PORTB as output movlw FS movwf TRISC ; PORTC as output GRAPHIC LCD control/FS clrf TRISD ; PORTD as output GRAPHIC LCD D0-D7 clrf TRISE ; PORTE as output movlw B'00000111' ;set LHS justify, RA0, RA1, RA3 as analog inputs movwf ADCON1 movlw B'10000110' ; pull-up Rs off (bit 7 hi), timer 1/25 sec movwf OPTION_REG ; (for 3.2768MHz xtal) PAGE0 movlw B'00011111' ; FS low, RST CD CE RD WR high movwf PORTC call PAUSIT goto GRAPHIC TABLE1 addwf PCL,F retlw '8' retlw '7' retlw '7' retlw ' ' retlw 'G' retlw 'R' retlw 'A' retlw 'P' retlw 'H' retlw 'I' retlw 'C' retlw ' ' retlw 'D' retlw 'E' retlw 'M' retlw 'O' retlw 'B' retlw 'A' retlw 'Z' retlw ' ' retlw 'W' retlw 'A' retlw 'S' retlw ' ' retlw ' ' retlw ' ' retlw 'H' retlw 'E' retlw 'R' retlw 'E' retlw ' ' retlw ' ' retlw '!' retlw '!' retlw 'T' retlw 'H' retlw 'I' retlw 'S' retlw ' ' retlw 'I' retlw 'S' retlw ' ' retlw 'P' retlw 'A' retlw 'G' retlw 'E' retlw ' ' retlw '2' GRAPHIC movlw 34 movwf COLUMN ;set column length call SETUP DEM1 call DEMO1 ; basic circuit diagram ;call WAITSW ; wait until switch pressed DEM2 call DEMO2 ; bit set/clear - square call WAITOFF ; wait until switch released goto GRAPHIC ; end of demo, restart from beginning ;****** DEMO 1 CREATE & SHOW SYMBOLS AS TEXT CHARACTERS ********** DEMO1 movlw B'10010100' ; text on, graphic off, cursor & blink off call SENDCMD ; send command ; SETUP USER CG RAM WORDS clrf ADRMSB movlw 0 ; set column call LINE0 ; set cell number for line stated movlw 16 ; character quantity movwf LOOPC ; clrf LOOPB ; clear table loop counter call SHWTXT ; clrf ADRMSB movlw 6 ; set column call LINE6 ; set cell number for line stated movlw 10 ; character quantity movwf LOOPC ; table loop counter remains at last call val call SHWTXT ; clrf ADRMSB movlw 6 ; set column call LINE7 ; set cell number for line stated movlw 8 ; character quantity movwf LOOPC ; table loop counter remains at last call val call SHWTXT ; clrf ADRMSB ; THIS GOES INTO PAGE 2 movlw 17 ; set column call LINE3 ; set cell number for line stated movlw 14 ; character quantity movwf LOOPC ; table loop counter remains at last call val call SHWTXT ; return ;********** DEMO 2 BIT SETTING/CLEARING DEMO **************** DEMO2 movlw B'10000000' ; internal CG RAM mode, OR mode call SENDCMD ; send command clrf ADRMSB ; TEXT HOME ADDRESS $00xx clrf ADRLSB ; set for PAGE 1 call CMDADR ; send command address movlw TXHOME ; call SENDCMD ; send command movlw B'10011100' ; text & graphic on, cursor & blink off call SENDCMD ; send command call INITLCD call HELLO here call PAUSE2 call Rcv_RS232 movwf byte1 call Rcv_RS232 ;SUBLW 64 ;SUBLW 16 movwf byte2 call Rcv_RS232 movwf byte3 call Rcv_RS232 movwf byte4 movlw 'O' CALL Xmit_RS232 movlw 'K' CALL Xmit_RS232 movf byte1,0 select case 'L' call LETTER movlw 'L' endcase case 'D' call DOT movlw 'D' endcase case 'C' call CLRTXT movlw 'C' endcase case 'X' return endcase case 'P' call WRBYTE movlw 'P' endcase case 'G' call CLRGRAPH movlw 'G' endcase case 'N' movf byte4 , 0 call PUTCHAR movlw 'N' endcase case '1' call CsrHome movlw '1' endcase case '2' call ALine2 movlw '2' endcase case 'B' call CLEARDISP movlw 'B' endcase case 'W' call I2C movlw 'W' endcase case 'Y' call BITE movlw 'Y' endcase case 'V' ;call CLRGRAPH ;call CLRTXT call BITE2 movlw 'V' endcase endselect goto here LETTER clrf ADRMSB clrf ADRLSB movf byte3,0 select case 0 movf byte2,0 call LINE0 goto txthere endcase case 1 movf byte2,0 call LINE1 goto txthere endcase case 2 movf byte2,0 call LINE2 goto txthere endcase case 3 movf byte2,0 call LINE3 goto txthere endcase case 4 movf byte2,0 call LINE4 goto txthere endcase case 5 movf byte2,0 call LINE5 goto txthere endcase case 6 movf byte2,0 call LINE6 goto txthere endcase case 7 movf byte2,0 call LINE7 goto txthere endcase endselect goto here txthere movlw 1 movwf LOOPC call SHOWIT goto here ;********** END DEMOS - START OF SUB-ROUTINES *************** WRBYTE movf byte2 , 0 MOVWF ADDR2 movf byte3 , 0 MOVWF ADDR1 CALL START MOVLW b'10100000' MOVWF OutputByte CALL OUT_BYTE CALL ACK MOVF ADDR2 , 0 ; INTO ADDR2 MOVWF OutputByte CALL OUT_BYTE CALL ACK MOVF ADDR1 , 0 MOVWF OutputByte CALL OUT_BYTE CALL ACK MOVF byte4 , 0 MOVWF OutputByte CALL OUT_BYTE CALL ACK CALL STOP RETURN DOT movf byte2 , 0 ; set column number movwf ADRLSB movf byte3 , 0 ; set graph line call GLINE ; multiply by line length to get address movf byte4 , 0 ADDLW B'11111000' call BITWRITE return BITE movf byte2 , 0 ; set column number movwf ADRLSB movf byte3 , 0 ; set graph line call GLINE ; multiply by line length to get address movf byte4 , 0 call ONEWRITE return BITE2 MOVF byte3 , 0 MOVWF ADDR1 MOVF byte2 , 0 MOVWF ADDR2 MOVLW 0 MOVWF PX MOVWF PY MOVLW 16 MOVWF BX MOVLW 64 MOVWF BY MOVLW b'10100000' MOVWF OutputByte CALL START CALL OUT_BYTE CALL ACK MOVF ADDR2 ,0 MOVWF OutputByte CALL OUT_BYTE CALL ACK MOVF ADDR1 , 0 MOVWF OutputByte CALL OUT_BYTE CALL ACK NEXT CALL START MOVLW b'10100001' MOVWF OutputByte CALL OUT_BYTE CALL ACK CALL IN_BYTE CALL NACK CALL STOP MOVF PX , 0 MOVWF ADRLSB MOVF PY , 0 CALL GLINE MOVF Data_Buf , 0 ;DATA READ INTO Data_Buf CALL ONEWRITE INCF PX ,1 DECFSZ BX , 1 GOTO NEXT INCF PY , 1 MOVLW 16 MOVWF BX CLRF PX DECFSZ BY , 1 GOTO NEXT RETURN RETURN SHOWIT ; ** SHOW TEXT HELD IN TABLE ** call SCREENADR ; set screen write address - vals preset at call movlw AWRON ; SET AUTO WRITE ON call SENDCMD ; send command movf byte4,0 addlw 224 ; +224 is same as -32 for conversion from ASCII call OUTDATA ; auto write and increment movlw AWROFF ; AUTO WRITE OFF call SENDCMD ; send command return I2C MOVf byte4 , 0 MOVWF READXCHARS movf byte2 , 0 MOVWF ADDR2 movf byte3 , 0 MOVWF ADDR1 MOVLW b'10100000' MOVWF OutputByte CALL START CALL OUT_BYTE CALL ACK MOVF ADDR2 ,0 ; INTO ADDR2 MOVWF OutputByte CALL OUT_BYTE CALL ACK MOVF ADDR1 , 0 MOVWF OutputByte CALL OUT_BYTE CALL ACK AGAIN CALL START MOVLW b'10100001' MOVWF OutputByte CALL OUT_BYTE CALL ACK CALL IN_BYTE CALL NACK CALL STOP MOVF Data_Buf , 0 ;DATA READ INTO Data_Buf CALL PUTCHAR INCF ADDR1 , 1 DECFSZ READXCHARS , 1 GOTO AGAIN RETURN Xmit_RS232 MOVWF Xmit_Byte ;move W to Xmit_Byte MOVLW 0x08 ;set 8 bits out MOVWF Bit_Cntr BCF PORTA, Ser_Out CALL Bit_Delay Ser_Loop RRF Xmit_Byte , f ;send one bit BTFSS STATUS , C BCF PORTA, Ser_Out BTFSC STATUS , C BSF PORTA, Ser_Out CALL Bit_Delay DECFSZ Bit_Cntr , f ;test if all done GOTO Ser_Loop BSF PORTA, Ser_Out CALL Bit_Delay RETURN Rcv_RS232 BTFSC PORTA, Ser_In ;wait for start bit GOTO Rcv_RS232 CALL Start_Delay ;do half bit time delay BTFSC PORTA, Ser_In ;check still in start bit GOTO Rcv_RS232 MOVLW 0x08 ;set up to read 8 bits MOVWF Bit_Cntr CLRF Rcv_Byte Next_RcvBit CALL Bit_Delay BTFSS PORTA, Ser_In BCF STATUS , C BTFSC PORTA, Ser_In BSF STATUS , C RRF Rcv_Byte , f DECFSZ Bit_Cntr , f ;test if all done GOTO Next_RcvBit CALL Bit_Delay MOVF Rcv_Byte, W RETURN Start_Delay MOVLW 0x0C MOVWF Delay_Count Start_Wait NOP DECFSZ Delay_Count , f GOTO Start_Wait RETURN Bit_Delay MOVLW 0x18 MOVWF Delay_Count Bit_Wait NOP DECFSZ Delay_Count , f GOTO Bit_Wait RETURN BITWRITE ; ** WRITE SINGLE SINGLE BIT DATA ROUTINE ** movwf BITVAL call SCREENADR ; set screen write address movf BITVAL,W call SENDCMD ; send command return ; ;......... ONEWRITE ; ** WRITE SINGLE BYTE ** movwf ATTRIB ; temp store val brought in on W call SCREENADR ; set screen write address - vals preset at call movlw AWRON ; AUTO WRITE ON call SENDCMD ; send command movf ATTRIB,W call OUTDATA ; movlw AWROFF ; AUTO WRITE OFF call SENDCMD ; send command return ;............ CMDADR ; ** SET ADDRESS FOR COMMAND SENDING ** movf ADRLSB,W ; WRITE DATA D1 call OUTDATA ; movf ADRMSB,W ; WRITE DATA D2 call OUTDATA ; return ; ;......... SCREENADR ; ** SET ADDRESS FOR WRITE/READ TO/FROM SCREEN movf ADRLSB,W ; WRITE ADDRESS LSB call OUTDATA ; movf ADRMSB,W ; WRITE ADDRESS MSB call OUTDATA ; movlw ADPSET ; SET ADDRESS POINTER call SENDCMD ; send command return ; ;............. TEXTHOME ; ** SET TEXT HOME ADDRESS ** clrf ADRMSB ; TEXT HOME ADDRESS $0000 clrf ADRLSB ; call CMDADR ; send command address movlw TXHOME ; call SENDCMD ; send command return ;........... GRAPHHOME ; ** SET GRAPHIC HOME ADDRESS ** movlw H'02' ; GRAPHIC HOME ADDRESS $0200 movwf ADRMSB clrf ADRLSB call CMDADR ; send command address movlw GRHOME ; call SENDCMD ; send command return ;........... TEXTAREA ; ** SET TEXT AREA ** clrf ADRMSB ; movf COLUMN,W ; columns length movwf ADRLSB ; call CMDADR ; send command address movlw TXAREA ; text area command call SENDCMD ; send command return ;........... GRAPHAREA ; ** SET GRAPHIC AREA ** clrf ADRMSB ; movf COLUMN,W ; columns length movwf ADRLSB ; call CMDADR ; send command address movlw GRAREA ; graphic area command call SENDCMD ; send command return ;........... CSRADR ; ** SET CURSOR POSITION ** call CMDADR ; send command address movlw CSRPOS ; cursor position command call SENDCMD ; send command return ;........... CSRTYP ; ** SET CURSOR TYPE ** movlw B'10100111' ; 8-line call SENDCMD ; send command return ; OPTIONS: ; %10100000 ; 1-line ; %10100001 ; 2-line ; %10100010 ; 3-line ; %10100011 ; 4-line ; %10100100 ; 5-line ; %10100101 ; 6-line ; %10100110 ; 7-line ; %10100111 ; 8-line ;........... SETMODE ; ** SET MODE - MANY OPTIONS, see EPE text ** movlw B'10000000' ; (OR mode, Internal CG mode) ; movlw %10000000 ; External CG RAM mode, OR ; movlw %10000011 ; External CG RAM mode, AND ; movlw %10000001 ; External CG RAM mode, XOR ; movlw %10000100 ; text attribute mode call SENDCMD ; send command return ; %1000x000 ; OR mode ; %1000x001 ; XOR mode ; %1000x011 ; AND mode ; %1000x100 ; Text Attribute mode ; %10000xxx ; Internal CG ROM mode ; %10001xxx ; External CG RAM mode ;........... SETOFFSET ; ** SET OFFSET REGISTER ** ; setting OFFSET address at 2 selects ; CG RAM START ADDRESS = $1400 where ; $80 is character number of 1st graphic byte ; values below that call ASCII text characters clrf ADRMSB ; movlw 2 ; movwf ADRLSB ; call CMDADR ; send command address movlw OFFSET ; call SENDCMD ; send command return ;........... SETDISPLAY ; ** DISPLAY MODE ** SOME OPTIONS: movlw B'10010100' ; text on, graphic off, cursor & blink off ; movlw %10011100 ; text on, graphic on, cursor & blink off ; movlw %10011000 ; text off, graphic on, cursor & blink off call SENDCMD ; send command return ; OTHER OPTIONS: ; %10010000 display off ; %1001xx10 cursor on, blink off ; %1001xx11 cursor on, blink on ; %100101xx text on, graphic off ; %100110xx text off, graphic on ; %100111xx text on, graphic on ;........... CLRTXT ; ** CLEAR TEXT AREA ($0000) ** clrf ADRMSB ; clear all text screen lines, length as set clrf ADRLSB ; call SCREENADR ; set screen write address movlw AWRON ; AUTO WRITE ON call SENDCMD ; send command movlw 8 ; number of lines movwf LOOPC CLR2 movf COLUMN,W ; column length movwf LOOPB ; CLR3 movlw 0 ; write 0 call OUTDATA ; auto write and increment decfsz LOOPB,F ; goto CLR3 ; decfsz LOOPC,F ; goto CLR2 ; movlw AWROFF ; AUTO WRITE OFF call SENDCMD ; send command return ;............ CLRGRAPH ; ** CLEAR GRAPH AREA ($0200) ** movlw H'02' movwf ADRMSB ; clrf ADRLSB ; call SCREENADR ; set screen write address movlw AWRON ; AUTO WRITE ON call SENDCMD ; send command movlw 64 ; number of lines movwf LOOPC CLRG2 movf COLUMN,W ; column length movwf LOOPB ; CLRG3 movlw 0 ; write 0 call OUTDATA ; auto write and increment decfsz LOOPB,F ; goto CLRG3 ; decfsz LOOPC,F ; goto CLRG2 ; movlw AWROFF ; AUTO RESET OFF call SENDCMD ; send command return ;.............. CLRCG ; ** CLEAR CG RAM AREA ($1400) ** movlw H'14' movwf ADRMSB ; clrf ADRLSB ; call SCREENADR ; set screen write address movlw AWRON ; AUTO WRITE ON call SENDCMD ; send command movlw 64 ; number of lines movwf LOOPC CLRCG2 movf COLUMN,W ; column length movwf LOOPB ; CLRCG3 movlw 0 ; write 0 call OUTDATA ; auto write and increment decfsz LOOPB,F ; goto CLRCG3 ; decfsz LOOPC,F ; goto CLRCG2 ; movlw AWROFF ; AUTO RESET OFF call SENDCMD ; send command return ;............ SETCG ; ** SETUP USER CG RAM ** movlw H'14' ; CG RAM start address 1400H movwf ADRMSB ; clrf ADRLSB ; call SCREENADR ; set screen write address movlw AWRON ; SET DATA AUTO WRITE ON call SENDCMD ; send command clrf LOOPB ; SETCG2 movf LOOPB,W ; WRITE TO EXTERNAL RAM ;call CGTABLE ; get table data call OUTDATA ; auto write and increment incf LOOPB,F ; decfsz LOOPC,F ; LOOPC val specified by calling routine goto SETCG2 ; movlw AWROFF ; AUTO WRITE OFF call SENDCMD ; send command return ;.............. SHWTXT ; ** SHOW TEXT HELD IN TABLE ** call SCREENADR ; set screen write address - vals preset at call movlw AWRON ; SET AUTO WRITE ON call SENDCMD ; send command SHTXT1 movf LOOPB,W ; LOOPB val specified by calling routine call TABLE1 ; get table data and convert to graphic LCD val addlw 224 ; +224 is same as -32 for conversion from ASCII call OUTDATA ; auto write and increment incf LOOPB,F ; decfsz LOOPC,F ; LOOPC val specified by calling routine goto SHTXT1 ; movlw AWROFF ; AUTO WRITE OFF call SENDCMD ; send command return ;.............. SETATTR ; ** SEND ATTRIBUTE & OTHER DATA TO SCREEN AS 1 CHARACTER, LOOPED call SCREENADR ; set screen write address - vals preset at call movlw AWRON ; AUTO WRITE ON call SENDCMD ; send command SETAT movf ATTRIB,W ; val to be sent preset at call call OUTDATA ; auto write and increment decfsz LOOPC,F ; LOOPC val specified by calling routine goto SETAT ; movlw AWROFF ; AUTO WRITE OFF call SENDCMD ; send command return ;............ SHOWCG ; ** SHOW USER CG RAM IN ORDER HELD BY TABLE ** call SCREENADR ; set screen write address - vals preset at call movlw AWRON ; AUTO WRITE ON call SENDCMD ; send command SHWCG2 movf LOOPB,W ; ;call AMPLIFIER ; get table data call OUTDATA ; auto write and increment incf LOOPB,F ; decfsz LOOPC,F ; LOOPC val specified by calling routine goto SHWCG2 ; movlw AWROFF ; AUTO WRITE OFF call SENDCMD ; send command return ;......... SENDCMD movwf PORTD bsf CLKCNT , 5 SC decfsz CLKCNT , F goto SC movlw B'00011010' movwf PORTC goto DWELL OUTDATA movwf PORTD movlw B'00010010' movwf PORTC DWELL bsf CLKCNT , 0 TIME decfsz CLKCNT, F goto TIME bsf PORTC , 2 return ;............. DATAREAD ; ** DATA READ ROUTINE ** movlw PEEK ; screen peek command call SENDCMD ; send command PAGE1 ; movlw 255 ; movwf TRISD ; set PORTD as inputs PAGE0 ; RST CD CE RD WR movlw B'00011001' ; 1 1 0 0 1 movwf PORTC ; set CE, RD low nop DR1 btfsc PORTD,6 ; is PORTD STATUS bit 6 low? goto DR1 ; no DR2 btfss PORTD,0 ; is PORTD STATUS bit 0 high? goto DR2 ; no DR3 btfss PORTD,1 ; is PORTD STATUS bit 1 high? goto DR3 ; no bcf PORTC,3 ; set CD low nop movf PORTD,W ; read data value movwf RDBYTE ; store read value ; RST CD CE RD WR movlw B'00011111' ; 1 1 1 1 1 movwf PORTC ; set controls PAGE1 ; clrf TRISD ; set PORTD as outputs PAGE0 ; return ;........... LINE7 addwf COLUMN,W ; sets line addresses for text screen btfsc STATUS,C incf ADRMSB,F LINE6 addwf COLUMN,W btfsc STATUS,C incf ADRMSB,F LINE5 addwf COLUMN,W btfsc STATUS,C incf ADRMSB,F LINE4 addwf COLUMN,W btfsc STATUS,C incf ADRMSB,F LINE3 addwf COLUMN,W btfsc STATUS,C incf ADRMSB,F LINE2 addwf COLUMN,W btfsc STATUS,C incf ADRMSB,F LINE1 addwf COLUMN,W btfsc STATUS,C incf ADRMSB,F LINE0 movwf ADRLSB ; COLUMN sets number of cells per line return ; ADRMSB is set/cleared before routine called ;.............. GLINE ;** GET GRAPHIC LINE ADDRESS ** movwf LOOPB ; store line val movlw 2 ; set graphic base address ($02xx) movwf ADRMSB movf LOOPB,W ; line val = 0? btfsc STATUS,Z return ; yes GLIN2 movf COLUMN,W ; no, multiply line length by line val addwf ADRLSB,F movlw 1 andwf STATUS,W ; extract and add CARRY (if any) to MSB addwf ADRMSB,F decfsz LOOPB,F goto GLIN2 return ;............ ;READ DATA FROM EEPROM ROUTINE modified for PIC16F87x devices ; according to data sheet DS30292A page 43 ; Routine entered with eeprom byte address preset PRMGET bsf STATUS,RP1 ; set for Page 2 bsf STATUS,RP0 ; set for Page 3 bcf EECON1,EEPGD ; point to data memory bsf EECON1,RD ; enable read flag bcf STATUS,RP0 ; set for Page 2 movf EEDATA,W ; read eeprom data into W incf EEADR,F ; inc address bcf STATUS,RP1 ; set for Page 0 return ;......... WAITSW btfsc PORTA,4 ; wait for switch press goto WAITSW call PAUSIT ; allow for switch bounce, then wait switch release WAITOFF ; wait for switch release WT2 btfss PORTA,4 goto WT2 call PAUSIT ; allow for switch bounce return ;................ PAUSIT movlw 5 ; pause routine, 1/5th sec movwf CLKCNT clrf INTCON PAUSE btfss INTCON,2 goto PAUSE bcf INTCON,2 decfsz CLKCNT,F goto PAUSE return ;................ PAUSE2 movlw 1 ; pause routine, 1/25th sec movwf CLKCNT clrf INTCON PAUS2 btfss INTCON,2 goto PAUSE bcf INTCON,2 decfsz CLKCNT,F goto PAUS2 return ;.............. SETUP ; RST CD CE RD WR GENERAL SETUP movlw B'00011111' ; 1 1 1 1 1 movwf PORTC ; set controls high (off) call TEXTHOME ; SET TEXT HOME ADDRESS call GRAPHHOME ; SET GRAPHIC HOME ADDRESS call TEXTAREA ; SET TEXT AREA call GRAPHAREA ; SET GRAPHIC AREA call SETMODE ; SET MODE (INT/EXT/AND-OR-XOR etc) call SETOFFSET ; SET OFFSET (see EPE text) call SETDISPLAY ; DISPLAY MODE (text, graph on/off etc) call CLRTXT ; WRITE TEXT BLANK CODE $0000 call CLRGRAPH ; WRITE GRAPH BLANK CODE $0200 call CLRCG ; WRITE CGRAM BLANK CODE $1400 return ;.............. CLEARDISP CALL CONTROL MOVLW 0X01 CALL PUTCHAR CALL DAT RETURN ALine2 CALL CONTROL MOVLW 0XA8 CALL PUTCHAR CALL DAT RETURN CsrHome CALL CONTROL MOVLW 0X02 CALL PUTCHAR CALL DAT RETURN PUTCHAR movwf BYTE CALL PING SWAPF BYTE , 1 CALL PING RETURN INITLCD CALL CONTROL MOVLW 0X30 MOVWF BYTE CALL PING MOVLW 0X20 MOVWF BYTE CALL PING MOVLW 0X0C ;NO UNDERLINE OR BLINK MOVWF BYTE CALL PING SWAPF BYTE , 1 CALL PING CALL DAT RETURN DAT BSF PORTB , 4 RETURN CONTROL BCF PORTB , 4 RETURN PING BTFSC BYTE , 7 BSF PORTB , 3 BTFSS BYTE , 7 BCF PORTB , 3 BTFSC BYTE , 6 BSF PORTB , 2 BTFSS BYTE , 6 BCF PORTB , 2 BTFSC BYTE , 5 BSF PORTB , 1 BTFSS BYTE , 5 BCF PORTB , 1 BTFSC BYTE , 4 BSF PORTB , 0 BTFSS BYTE , 4 BCF PORTB , 0 BSF PORTB , 5 MOVLW 0x01 CALL DELAY BCF PORTB , 5 RETURN HELLO CALL CLEARDISP MOVLW 'R' CALL PUTCHAR MOVLW 'E' CALL PUTCHAR MOVLW 'A' CALL PUTCHAR MOVLW 'D' CALL PUTCHAR MOVLW 'Y' CALL PUTCHAR RETURN DELAY MOVWF DEL DELLOOP CALL DEL100 DECFSZ DEL , 1 GOTO DELLOOP RETURN DEL100 MOVLW 0X4D ;0X8D MOVWF D1 DELAY_00 MOVLW 0X7B ;0XEB MOVWF D2 DELAY_01 DECFSZ D2 , 1 GOTO DELAY_01 DECFSZ D1 , 1 GOTO DELAY_00 MOVLW 0X08 MOVWF D1 DELAY_10 DECFSZ D1 , 1 GOTO DELAY_10 NOP RETURN IN_BYTE ; read byte on i2c bus CLRF Data_Buf MOVLW 8 MOVWF _N ; set index to 8 CALL HIGH_SDA ; be sure SDA is configured as input IN_BIT CALL HIGH_SCL ; clock high BTFSS PORTC, SDA ; test SDA bit GOTO IN_ZERO GOTO IN_ONE IN_ZERO BCF STATUS, C ; clear any carry RLF Data_Buf, F ; i_byte = i_byte << 1 | 0 GOTO CONT_IN IN_ONE BCF STATUS, C ; clear any carry RLF Data_Buf, F INCF Data_Buf, F ; i_byte = (i_byte << 1) | 1 GOTO CONT_IN CONT_IN CALL LOW_SCL ; bring clock low DECFSZ _N, F ; decrement index GOTO IN_BIT RETURN ;;;;;; OUT_BYTE ; send o_byte on I2C bus MOVLW 8 MOVWF _N OUT_BIT BCF STATUS,C ; clear carry RLF OutputByte, F ; left shift, most sig bit is now in carry BTFSS STATUS, C ; if one, send a one GOTO OUT_ZERO GOTO OUT_ONE OUT_ZERO CALL LOW_SDA ; SDA at zero CALL CLOCK_PULSE CALL HIGH_SDA GOTO OUT_CONT OUT_ONE CALL HIGH_SDA ; SDA at logic one CALL CLOCK_PULSE GOTO OUT_CONT OUT_CONT DECFSZ _N, F ; decrement index GOTO OUT_BIT RETURN ;;;;;; NACK ; bring SDA high and clock CALL HIGH_SDA CALL CLOCK_PULSE RETURN ACK CALL LOW_SDA CALL CLOCK_PULSE RETURN START CALL LOW_SCL CALL HIGH_SDA CALL HIGH_SCL CALL LOW_SDA ; bring SDA low while SCL is high CALL LOW_SCL RETURN STOP CALL LOW_SCL CALL LOW_SDA CALL HIGH_SCL CALL HIGH_SDA ; bring SDA high while SCL is high CALL LOW_SCL RETURN CLOCK_PULSE ; SCL momentarily to logic one CALL HIGH_SCL CALL LOW_SCL RETURN HIGH_SDA ; high impedance by making SDA an input BSF STATUS, RP0 ; bank 1 BSF PORTC, SDA ; make SDA pin an input BCF STATUS, RP0 ; back to bank 0 CALL DELAY_SHORT RETURN LOW_SDA BCF PORTC, SDA BSF STATUS, RP0 ; bank 1 BCF PORTC, SDA ; make SDA pin an output BCF STATUS, RP0 ; back to bank 0 CALL DELAY_SHORT RETURN HIGH_SCL BSF STATUS, RP0 ; bank 1 BSF PORTC, SCL ; make SCL pin an input BCF STATUS, RP0 ; back to bank 0 CALL DELAY_SHORT RETURN LOW_SCL BCF PORTC, SCL BSF STATUS, RP0 ; bank 1 BCF PORTC, SCL ; make SCL pin an output BCF STATUS, RP0 ; back to bank 0 CALL DELAY_SHORT RETURN DELAY_SHORT ; provides nominal 25 usec delay MOVLW 5 MOVWF LOOP2 DELAY_SHORT_1 NOP DECFSZ LOOP2, F GOTO DELAY_SHORT_1 RETURN DELAY_LONG ; provide 250 ms delay MOVLW 250 MOVWF LOOP1 OUTTER MOVLW 110 ; close to 1.0 msec delay when set to .110 MOVWF LOOP2 INNER NOP NOP NOP NOP NOP NOP DECFSZ LOOP2, F ; decrement and leave result in LOOP2 ; skip next statement if zero GOTO INNER DECFSZ LOOP1, F GOTO OUTTER RETURN end