;Here's the LCD source. Pretty easy stuff. Change the timing to suit ;your needs. ;Now does anyone have good serial port routines? I need something that ;can easily adapt up to 9600 by simply changing a constant. ; ;********************************************************************* ;* The LCDer, By Mik Juneau Kim * ;* June 4, 1997 11:58 PM * ;********************************************************************* ;* This project has nothing to do with my employer. I developed this * ;* on my own time. However, I reserve the copyright to this code. * ;* This code is shared freely with the public. Any damage in any * ;* shape or form arising out of the use of this code is _NOT_ my * ;* responsibility. The user of this code assumes the full liability. * ;* Now back to our regularly scheduled programming... * ;********************************************************************* LIST P=16C84,F=INHX8M include "P16C84.INC" __FUSES _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC SYS_CLK EQU D'4000000' DELAY1 EQU SYS_CLK / D'400000';Combination of DELAY1 and DELAY2 make DELAY2 EQU D'10' ;it dynamic, although only one can be used COUNT1 EQU 0C ;temp storage for delay COUNT2 EQU 0D ;temp storage for delay LCDAddr EQU 0E ;LCD address LCDData EQU 0F ;LCD data to send (2 nibbles) ORG 0 InitLCD ; RB7=data/control RB3=Data3 ; RB6=latch RB2=Data2 ; RB5=N/A (input) RB1=Data1 ; RB4=N/A (input) RB0=Data0 CLRF PORTB ;Clear portB MOVLW 0x30 ;Set portB stuff BSF STATUS,RP0 ;Bank0 MOVWF TRISB ; BCF STATUS,RP0 ;Bank1 MOVLW 80 MOVWF LCDAddr ;LCD start address = 80 hex start CALL WAIT ;startup delay CALL WAIT CALL WAIT CALL WAIT CALL WAIT CALL INIT_4BIT ;Init LCD for 4 bit mode CALL SYSTEM_SET ;Set the system (look it up in datasheet) CALL ENTRY_MODE CALL DISP_CONTROL CALL CLEAR_DISP ;Clear the display CALL SET_DDRAM ;Set the current display locaction to XX FIRST CALL WAIT CALL M CALL i CALL k CALL k CALL i CALL M CALL SPC GOTO FIRST SEND_LCD_CONTROL ;LCDData is dumped to LCDAddr, high nibble first MOVWF LCDData SWAPF LCDData,W ; ANDLW 0F ;Extract high nibble from LCDData MOVWF PORTB ;And put it into PORTB CALL CLOCK ;And Clock in the data MOVF LCDData,W ; ANDLW 0F ;Extract low nibble from LCDData MOVWF PORTB ;And put it into PORTB GOTO CLOCK ;Clock the data SEND_LCD_DATA ;W is dumped to LCDData then to (LCDAddr), high nibble first ;Also, the address is incremented and truncated as necessary MOVWF LCDData SWAPF LCDData,W ; ANDLW 0F ;Extract high nibble from LCDData IORLW 80 ;Databit is set high MOVWF PORTB ;And put it into PORTB CALL CLOCK ;And Clock in the data MOVF LCDData,W ; ANDLW 0F ;Extract low nibble from LCDData IORLW 80 ;Databit is set high MOVWF PORTB ;And put it into PORTB CALL CLOCK ;Clock the data INCF LCDAddr,F ;Increment the address MOVLW 90 ;Is it the end of line 1? XORWF LCDAddr,W ; BTFSS STATUS,Z ; GOTO CHK_LINE2 ; MOVLW 0xC0 ;End of line 1 reached MOVWF LCDAddr ;Put beginning of line 2 GOTO SET_DDRAM ; CHK_LINE2 ; MOVLW 0xD0 ;Is it the end of line 2? XORWF LCDAddr,W ; BTFSS STATUS,Z ; RETLW 0x00 ;Not the end of anything. Return MOVLW 0x80 ;End of line 2 reached MOVWF LCDAddr ;Put beginning of line 1 GOTO SET_DDRAM ; INIT_4BIT MOVLW 02 MOVWF PORTB GOTO CLOCK SYSTEM_SET MOVLW 2C GOTO SEND_LCD_CONTROL ENTRY_MODE MOVLW 06 GOTO SEND_LCD_CONTROL DISP_CONTROL MOVLW 0F GOTO SEND_LCD_CONTROL CLEAR_DISP MOVLW 80 MOVWF LCDAddr MOVLW 01 GOTO SEND_LCD_CONTROL SET_DDRAM MOVF LCDAddr,W GOTO SEND_LCD_CONTROL RET_HOME MOVLW 02 GOTO SEND_LCD_CONTROL M movlw 4D GOTO SEND_LCD_DATA i movlw 69 GOTO SEND_LCD_DATA k movlw 6B GOTO SEND_LCD_DATA SPC MOVLW 20 GOTO SEND_LCD_DATA WAIT MOVLW DELAY1 movwf COUNT1 d1 MOVLW DELAY2 movwf COUNT2 d2 decfsz COUNT2,1 goto d2 decfsz COUNT1,1 goto d1 retlw 00 CLOCK BCF PORTB,6 CALL WAIT BSF PORTB,6 CALL WAIT BCF PORTB,6 retlw 00 END