NEW! 416028 |
This is my first decent bit of code for the PICmicro. It's a display control library that was distributed to a few members of the PICList for testing. I have used the serial control library (lcd_ser.inc) extensively - LCDs make great debugging tools. Examine the examples carefully - almost all you need to know is contained in them.
A small bug in the 4-bit driver code was fixed on 26 May 2003. This bug meant that some display panels (such as the Optrex DMC16106C) would miss characters sent to the display.
LIST ; PIC16-series PAGE-switching macros ; By P. Pemberton, Jr. ; WWW: http://www.philpem.me.uk/ ; Email: piclist@philpem.me.uk ; This software is distributed under the BSD License. You are free to do whatever ; you want with this code, but I would appreciate an email first. I would also ; appreciate copies of any modifications you make. ; ; Provides: ; BANK0 Switch to RAM BANK 0 ; BANK1 Switch to RAM BANK 1 ; BANK2 Switch to RAM BANK 2 ; BANK3 Switch to RAM BANK 3 NOLIST #ifndef __BANKS_INCLUDED #define __BANKS_INCLUDED BANK0 MACRO ; Macro to select data RAM BANK 0 BCF STATUS,RP0 BCF STATUS,RP1 ENDM BANK1 MACRO ; Macro to select data RAM BANK 1 BSF STATUS,RP0 BCF STATUS,RP1 ENDM BANK2 MACRO ; Macro to select data RAM BANK 2 BCF STATUS,RP0 BSF STATUS,RP1 ENDM BANK3 MACRO ; Macro to select data RAM BANK 3 BSF STATUS,RP0 BSF STATUS,RP1 ENDM #endif LIST
; Universal PIC LCD Interface Module ; HD44780 main handler/common functions (LCD_CMN.INC) ; NOTE: DO NOT #INCLUDE THIS FILE - #INCLUDE ONE OF THE BACKENDS INSTEAD! ; By P. Pemberton, Jr. ; WWW: http://www.philpem.me.uk/ ; Email: piclist@philpem.me.uk ; This software is distributed under the BSD License. You are free to do whatever ; you want with this code, but I would appreciate an email first. I would also ; appreciate copies of any modifications you make. CBLOCK __LCD_DOCBUFF ; Display Control settings ENDC ; Initialize LCD LCD_INIT: MOVLW B'00000100' ; Init DOCBUFF MOVWF __LCD_DOCBUFF CALL __LCD_INIT ; Init the LCD RETURN ; Return ; Display Clear LCD_CLRSCR: MOVLW B'00000001' ; Clear the LCD display CALL LCD_SENDINS RETURN ; Display On/Off - If W=0 then display off else display on LCD_ONOFF: BSF __LCD_DOCBUFF, 2 ; Assume W != 0 IORLW 0 ; Update flags BTFSC STATUS, Z ; Zero? BCF __LCD_DOCBUFF, 2 ; W=0; turn off the display MOVF __LCD_DOCBUFF, W ; Move control byte into W IORLW .8 ; Set command bit CALL LCD_SENDINS ; Send the instruction RETURN ; Cursor On/Off - If W=0 then cursor off else cursor on LCD_CURSOR: BSF __LCD_DOCBUFF, 1 ; Assume W != 0 IORLW 0 ; Update flags BTFSC STATUS, Z ; Zero? BCF __LCD_DOCBUFF, 1 ; W=0; turn off the cursor MOVF __LCD_DOCBUFF, W ; Move control byte into W IORLW .8 ; Set command bit CALL LCD_SENDINS ; Send the instruction RETURN ; Blinking Cursor On/Off - If W=0 then blinking cursor on else off LCD_CURSBLINK: BSF __LCD_DOCBUFF, 0 ; Assume W != 0 IORLW 0 ; Update flags BTFSC STATUS, Z ; Zero? BCF __LCD_DOCBUFF, 0 ; W=0; turn off the block cursor MOVF __LCD_DOCBUFF, W ; Move control byte into W IORLW .8 ; Set command bit CALL LCD_SENDINS ; Send the instruction RETURN ; Move cursor - W=offset LCD_MOVECURS: IORLW B'10000000' ; Set command bit CALL LCD_SENDINS ; Send the instruction RETURN ; Move cursor to Line 1 LCD_LINE1: MOVLW 0x00 ; Move cursor to 0x00 CALL LCD_MOVECURS RETURN ; Move cursor to Line 2 LCD_LINE2: MOVLW 0x40 ; Move cursor to 0x40 CALL LCD_MOVECURS RETURN
; Universal PIC LCD Interface Module ; HD44780 4-bit mode transport layer/backend (LCD_4BIT.INC) ; By P. Pemberton, Jr. ; WWW: http://www.philpem.me.uk/ ; Email: piclist@philpem.me.uk ; This software is distributed under the BSD License. You are free to do whatever ; you want with this code, but I would appreciate an email first. I would also ; appreciate copies of any modifications you make. ; ; Pindefs required: ; LCD_D7 The PIC pin connected to the LCD's D7 pin (ex: PORTB,3) ; LCD_D6 The PIC pin connected to the LCD's D6 pin (ex: PORTB,2) ; LCD_D5 The PIC pin connected to the LCD's D5 pin (ex: PORTB,1) ; LCD_D4 The PIC pin connected to the LCD's D4 pin (ex: PORTB,0) ; LCD_E The PIC pin connected to the LCD's E pin (ex: PORTB,5) ; LCD_RS The PIC pin connected to the LCD's RS pin (ex: PORTB,4) CBLOCK __LCD_TEMP0 __LCD_TEMP1 ENDC ; Send a byte to the LCD, assumes RS already set __LCD_SEND: MOVWF __LCD_TEMP0 ; Store byte in Temp 0 BCF LCD_D7 ; Clear data bits BCF LCD_D6 BCF LCD_D5 BCF LCD_D4 BTFSC __LCD_TEMP0, 7 ; Load high nibble BSF LCD_D7 BTFSC __LCD_TEMP0, 6 BSF LCD_D6 BTFSC __LCD_TEMP0, 5 BSF LCD_D5 BTFSC __LCD_TEMP0, 4 BSF LCD_D4 BSF LCD_E ; Strobe E GOTO $+1 BCF LCD_E BCF LCD_D7 ; Clear data bits BCF LCD_D6 BCF LCD_D5 BCF LCD_D4 BTFSC __LCD_TEMP0, 3 ; Load low nibble BSF LCD_D7 BTFSC __LCD_TEMP0, 2 BSF LCD_D6 BTFSC __LCD_TEMP0, 1 BSF LCD_D5 BTFSC __LCD_TEMP0, 0 BSF LCD_D4 BSF LCD_E ; Strobe E GOTO $+1 BCF LCD_E RETURN ; Send an instruction byte to the LCD LCD_SENDINS: BCF LCD_RS ; RS low=instruction CALL __LCD_SEND ; Send the instruction byte CALL __LCD_SHORTDELAY ; Short delay for instruction RETURN ; Send a character to the LCD LCD_PUTCH: BSF LCD_RS ; RS high=character CALL __LCD_SEND ; Send the character CALL __LCD_SHORTDELAY ; Short delay for data RETURN ; Initialize the LCD __LCD_INIT: CALL __LCD_LONGDELAY ; Long init delay MOVLW B'00110011' ; 2x 8bit resets CALL LCD_SENDINS MOVLW B'00110011' ; 2x 8bit resets CALL LCD_SENDINS MOVLW B'00110010' ; 8bit reset then 4bit reset CALL LCD_SENDINS MOVLW B'00101100' ; Function Set - 4bit, 2 lines CALL LCD_SENDINS MOVLW B'00000110' ; Mode Set - incr. w/crsr shift CALL LCD_SENDINS MOVLW B'00001100' ; Display on, cursor & blink off CALL LCD_SENDINS MOVLW B'00000001' ; Display Clear CALL LCD_SENDINS MOVLW B'00000010' ; Cursor Home CALL LCD_SENDINS CALL __LCD_LONGDELAY ; Long post-init delay RETURN ; Long delay for init __LCD_LONGDELAY: CLRF __LCD_TEMP0 __LCD_LONGDEL: CLRF __LCD_TEMP1 __LCD_SHORTDEL: DECFSZ __LCD_TEMP1, F GOTO __LCD_SHORTDEL DECFSZ __LCD_TEMP0, F GOTO __LCD_LONGDEL RETURN ; Short delay between commands __LCD_SHORTDELAY: MOVLW 0x14 MOVWF __LCD_TEMP1 __LCD_SHORTLOOP: DECFSZ __LCD_TEMP1, F GOTO __LCD_SHORTLOOP RETURN ; Include the Common LCD Functions INCLUDE "lcd_cmn.inc"
; Universal PIC LCD Interface Module ; HD44780 serial mode transport layer/backend (LCD_SER.INC) ; By P. Pemberton, Jr. ; WWW: http://www.philpem.me.uk/ ; Email: piclist@philpem.me.uk ; This software is distributed under the BSD License. You are free to do whatever ; you want with this code, but I would appreciate an email first. I would also ; appreciate copies of any modifications you make. ; ; Pindefs required: ; LCD_DATA The PIC pin connected to the A and B pins on the ; 74LS164 (ex: PORTB,5) ; LCD_CLOCK The PIC pin connected to the LS164's CLOCK pin ; (ex: PORTB,4) INCLUDE "banks.inc" ; File register Usage CBLOCK __LCD_DLAY ; Delay variable __LCD_NOTEMP ; Temporary variable for nibble output __LCD_TEMP ; Temporary variable __LCD_CNTR ; Counter ENDC __LCD_INIT: CALL __LCD_DLAY5 ; Wait 20 msecs before Reset CALL __LCD_DLAY5 CALL __LCD_DLAY5 CALL __LCD_DLAY5 BCF STATUS, C ; RS=0 (instruction) MOVLW 0x30 ; RESET CALL __LCD_NIBBLE ; Send the nibble CALL __LCD_DLAY5 ; Wait 5mS before resending BSF LCD_DATA ; Send again. BCF LCD_DATA CALL __LCD_DLAY160 ; Wait 160uS before resending BSF LCD_DATA BCF LCD_DATA CALL __LCD_DLAY160 ; Wait 160uS before sending BCF STATUS, C ; RS=0 (instruction) MOVLW 0x20 ; Set 4-bit (nibble) mode CALL __LCD_NIBBLE ; Send the nibble CALL __LCD_DLAY160 ; Wait 160uS before sending MOVLW 0x28 ; Two line mode, 4-bit CALL LCD_SENDINS CALL __LCD_DLAY160 MOVLW 0x08 ; Turn off the display CALL LCD_SENDINS MOVLW 0x01 ; Clear the DDRAM CALL LCD_SENDINS CALL __LCD_DLAY5 ; Can take up to 5uS MOVLW 0x06 ; Set cursor direction CALL LCD_SENDINS MOVLW 0x0C ; Display on CALL LCD_SENDINS CALL __LCD_DLAY160 RETURN LCD_PUTCH: ; Send a character to the LCD MOVWF __LCD_DLAY ; Temporary store. BSF STATUS, C ; RS=1 (data) CALL __LCD_NIBBLE ; Send the high nibble SWAPF __LCD_DLAY, W ; Low nibble -> W BSF STATUS, C ; RS=1 (data) CALL __LCD_NIBBLE ; Send the low nibble RETURN LCD_SENDINS: ; Send an instruction to the LCD MOVWF __LCD_DLAY ; Temporary store BCF STATUS, C ; RS=0 (instruction) CALL __LCD_NIBBLE ; Send the high nibble SWAPF __LCD_DLAY, W ; Low nibble -> W BCF STATUS, C ; RS=0 (instruction) CALL __LCD_NIBBLE ; Send the low nibble RETURN __LCD_NIBBLE: ; Sends a nibble (4 bits) to the LCD MOVWF __LCD_NOTEMP ; Temporarily store the nibble RRF __LCD_NOTEMP, F ; Save the RS bit BSF STATUS, C ; Carry high RRF __LCD_NOTEMP, F ; Save the gate bit MOVLW .0 ; Clear the shift register CALL __LCD_SEND MOVF __LCD_NOTEMP, W ; Send the nibble to the LCD CALL __LCD_SEND BSF LCD_DATA ; Clock in the data BCF LCD_DATA RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Send the byte in W to the 74HCT164 __LCD_SEND: MOVWF __LCD_TEMP ; Store byte MOVLW .8 ; Eight data bits MOVWF __LCD_CNTR ; Store in counter __LCD_SENDLOOP: MOVLW 0 RLF __LCD_TEMP, F ; Rotate left into carry BCF LCD_DATA ; Assume carry low BTFSC STATUS, C ; Carry high? BSF LCD_DATA ; Yes. Set port bit ; GOTO $+1 ; Wait for the data line to settle BSF LCD_CLOCK ; Clock high ; GOTO $+1 ; Make sure the HC164 sees the transition BCF LCD_CLOCK ; Clock low DECFSZ __LCD_CNTR, F ; Decrement counter GOTO __LCD_SENDLOOP ; Not zero yet; keep going RETURN ; Counter=0; return. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; __LCD_DLAY160: ; 160uS delay MOVLW .256-(160/4) ; Loop until carry set ADDLW .1 BTFSS STATUS, C GOTO $-2 RETURN __LCD_DLAY5: ; 5mS delay MOVLW .4 ; Set up the Delay MOVWF __LCD_DLAY MOVLW .256 - 0x0E8 ; Inner loop ADDLW 1 BTFSC STATUS, Z DECFSZ __LCD_DLAY, F ; Outer loop GOTO $-3 RETURN ; Include the Common LCD Functions INCLUDE "lcd_cmn.inc"
; Universal PIC LCD Interface Module ; 74LS164-to-LCD test program ; By P. Pemberton, Jr. ; WWW: http://www.philpem.me.uk/ ; Email: piclist@philpem.me.uk ; This software is distributed under the BSD License. You are free to do whatever ; you want with this code, but I would appreciate an email first. I would also ; appreciate copies of any modifications you make. ; ; Connections: ; PIC 74LS164 LCD ; RB7 1 and 2 via 10k resistor to "E" ; RB6 8 ; 5 D4 ; 6 D5 ; 10 D6 ; 11 D7 ; 12 RS ; 13 to 1N4148 cathode ; Vcc 9 and 14 Vcc ; Vss 7 Vss ; E to 1N4148 anode ; ; ; The contrast pin on the LCD should be connected as shown in the LCD module's ; datasheet. ; ; The above circuit is based on one included in an article written by ; Myke Predko for www.rentron.com ;; PIC setup and toplevel includes LIST P=16F874 INCLUDE <p16f874.inc> INCLUDE "banks.inc" ; Pindefs #DEFINE LCD_DATA PORTB, 7 #DEFINE LCD_CLOCK PORTB, 6 ; Variables CBLOCK 0x20 ENDC ; Reset vector ORG 0 GOTO START ; Interrupt vector ORG 4 GOTO START ; Start of code ORG 5 START: CLRF PORTB ; Clear PORTB PAGE1 ; Bank 1 BCF LCD_DATA ; Data, clock=outputs BCF LCD_CLOCK PAGE0 ; Bank 0 CALL LCD_INIT ; Init the LCD CLRF FSR ; Message loop MSGLOOP: MOVF FSR, W INCF FSR, F CALL MESSAGE IORLW .0 BTFSC STATUS, Z GOTO MSGDONE CALL LCD_PUTCH GOTO MSGLOOP MSGDONE: MOVLW .1 ; Block Cursor on CALL LCD_CURSBLINK CALL LCD_LINE2 MOVLW "2" CALL LCD_PUTCH MOVLW "0" CALL LCD_PUTCH MOVLW "." CALL LCD_PUTCH MOVLW "0" CALL LCD_PUTCH MOVLW 0x1A CALL LCD_PUTCH GOTO $ MESSAGE: ADDWF PCL, F DT "Hello.",0 ;; Final post-code includes INCLUDE "lcd_ser.inc" END
; Universal PIC LCD Interface Module ; 4-bit LCD test program ; By P. Pemberton, Jr. ; WWW: http://www.philpem.me.uk/ ; Email: piclist@philpem.me.uk ; This software is distributed under the BSD License. You are free to do whatever ; you want with this code, but I would appreciate an email first. I would also ; appreciate copies of any modifications you make. ; ; Connections: ; PIC LCD ; RB5 E ; RB4 RS ; RB3 D7 ; RB2 D6 ; RB1 D5 ; RB0 D4 ; ; The contrast pin on the LCD should be connected as shown in the LCD module's ; datasheet. ;; PIC setup and toplevel includes LIST P=16F874 INCLUDE <p16f874.inc> INCLUDE "banks.inc" ; Pindefs #DEFINE LCD_D7 PORTB, 3 #DEFINE LCD_D6 PORTB, 2 #DEFINE LCD_D5 PORTB, 1 #DEFINE LCD_D4 PORTB, 0 #DEFINE LCD_E PORTB, 5 #DEFINE LCD_RS PORTB, 4 ; Variables CBLOCK 0x20 ENDC ; Reset vector ORG 0 GOTO START ; Interrupt vector ORG 4 GOTO START ; Start of code ORG 5 START: CLRF PORTB ; Clear PORTB PAGE1 ; Bank 1 BCF LCD_D7 ; Databits=outputs BCF LCD_D6 BCF LCD_D5 BCF LCD_D4 BCF LCD_RS ; RS, E=outputs BCF LCD_E PAGE0 ; Bank 0 CALL LCD_INIT ; Init the LCD CLRF FSR ; Message loop MSGLOOP: MOVF FSR, W INCF FSR, F CALL MESSAGE IORLW .0 BTFSC STATUS, Z GOTO MSGDONE CALL LCD_PUTCH GOTO MSGLOOP MSGDONE: MOVLW .1 ; Blinking Cursor on CALL LCD_CURSBLINK CALL LCD_LINE2 MOVLW "2" CALL LCD_PUTCH MOVLW "0" CALL LCD_PUTCH MOVLW "." CALL LCD_PUTCH MOVLW "0" CALL LCD_PUTCH MOVLW 0x1A CALL LCD_PUTCH GOTO $ MESSAGE: ADDWF PCL, F DT "Hello.",0 ;; Final post-code includes INCLUDE "lcd_4bit.inc" END
Comments: