NEW! 416028 |
Simple routines for controlling a HD44780 display. Useful if you are adding a display to an old project. The data bus and control lines can use any pin. It works just fine on pic 16f677 and 16f877.
Code:
;********************************************************************** ; Simple routines for controlling a HD44780 display * ; Useful if you are adding a display to an old project. * ; The data bus and control lines can use any pin. * ; If the pin is open collector you need a pull up resistor * ; * ;********************************************************************** ; * ; Filename: lcd.asm * ; Date: 20080204 * ; File Version: 1.1 * ; * ; Author: Stefan Johansson * ; tessier at telia dot com * ; * ;********************************************************************** ; * ; Usage: #include <lcd.asm> * ; call LCDINIT ; Initialize LCD * ; * ; movlw 0x05 * ; call LCDADD ; Goto lcd adress 0x05* ; * ; movlw 'A' * ; call LCDSEND ; Write character A * ;********************************************************************** ; * ; Variables: D0 * ; D1 * ; D2 * ; LCDTmp * ; * ;********************************************************************** ; * ; Notes: This was written and compiled for PIC 16f677. * ; Modification might be needed for other models. * ; Any comments, questions or improvements... mail me * ; * ;********************************************************************** ; LCD control lines ; Modify to match your project #define LCD_D4 PORTB, 3 #define LCD_D5 PORTB, 2 ; 4 data lines #define LCD_D6 PORTB, 1 #define LCD_D7 PORTB, 0 #define LCD_RS PORTB, 5 ; 0 = Command, 1 = Data #define LCD_E PORTB, 4 ; 1 to send data ;************************************************************* ; Initialize LCD functions ;************************************************************* LCDINIT ; Set correct TRIS values for LCD ports bsf STATUS, RP0 ;Bank 1 bcf LCD_RS bcf LCD_E bcf LCD_D4 bcf LCD_D5 bcf LCD_D6 bcf LCD_D7 bcf STATUS, RP0 ;Bank 0 movlw 0x40 ; Initial delay, probably not needed... call delay ; Forced LCD initialization bcf LCD_RS ; Set command mode bcf LCD_E bsf LCD_D4 bsf LCD_D5 bcf LCD_D6 bcf LCD_D7 call PULSE movlw 0x04 call delay call PULSE call short_dly call short_dly call PULSE ; Send the command to select 4-bit mode first bcf LCD_D4 call PULSE ; Function set ; Format: xxxDNFxx D: 1= 8-bit, 0= 4-bit (use 4-bit!) movlw b'00101000' ; N: 1= 2 lines, 0= 1 line call LCDSEND ; F: 1= 5x10 font, 0= 5x8 font ; Display control ; Format: xxxxxDCB D: Display on(1)/0ff(0) movlw b'00001100' ; C: Cursor on(1)/0ff(0) call LCDSEND ; B: Blink on(1)/0ff(0) ; Entry mode set ; Format: xxxxxxIS I: 1= Increment counter, 0= Decrement counter movlw b'00000110' ; S: 1= "Accompanies display shift" call LCDSEND ; Cursor or display shift ; Format: xxxxSRxx S: 1= Display shift, 0= Cursor move movlw b'00010000' ; R: 1= Shift right, 0= Shift left call LCDSEND movlw b'00000001' ; Clear screen call LCDSEND bsf LCD_RS ; Set data mode RETURN ;************************************************************* ; Moves "cursor" ;************************************************************* LCDADD bcf LCD_RS ; Command mode iorlw 0x80 ; Goto DDRAM adress call LCDSEND bsf LCD_RS ; Data mode call delay_1ms ; Takes a couple of ms RETURN ;************************************************************* ; Sends contens of W to display ;************************************************************* LCDSEND ; Sends character in W to lcd. Does not alter RS line! movwf LCDTmp bcf LCD_D4 bcf LCD_D5 bcf LCD_D6 bcf LCD_D7 btfsc LCDTmp, 7 bsf LCD_D7 btfsc LCDTmp, 6 bsf LCD_D6 btfsc LCDTmp, 5 bsf LCD_D5 btfsc LCDTmp, 4 bsf LCD_D4 call PULSE bcf LCD_D4 bcf LCD_D5 bcf LCD_D6 bcf LCD_D7 btfsc LCDTmp, 3 bsf LCD_D7 btfsc LCDTmp, 2 bsf LCD_D6 btfsc LCDTmp, 1 bsf LCD_D5 btfsc LCDTmp, 0 bsf LCD_D4 call PULSE return ;************************************************************* ; Pulse enable line ;************************************************************* PULSE ; Pulse Enable. bsf LCD_E nop ; Increase the delay here if you get nop ; problems with high clock speed nop ; Probably not needed since nop ; 1 instruction @10MHz = 400ns bcf LCD_E call delay_1ms call delay_1ms return ;************************************************************* ; Clears display ;************************************************************* LCDCLR ; clears the entire display bcf LCD_RS ; Set command mode movlw b'00000001' ; Clear screen call LCDSEND bsf LCD_RS ; Set data mode return ;************************************************************* ; Calls the delay_1ms W times ;************************************************************* delay movwf d0 dly_loop call delay_1ms decfsz d0, F goto dly_loop return ;************************************************************* ; 1ms delay. ; Modify this to match your processor speed. ; http://www.piclist.com/techref/piclist/codegen/delay.htm ;************************************************************* delay_1ms movlw 0xF3 ;2498 cycles movwf d1 movlw 0x02 movwf d2 Delay_0 decfsz d1, f goto $+2 decfsz d2, f goto Delay_0 goto $+1 ;2 cycles return ;4 cycles (including call) ;************************************************************* ; 40us delay. ; Modify this to match your processor speed. ; http://www.piclist.com/techref/piclist/codegen/delay.htm ;************************************************************* short_dly movlw 0x1F ;94 cycles movwf d1 short_dly_0 decfsz d1, f goto short_dly_0 goto $+1 ;2 cycles return ;4 cycles (including call)
Comments:
#include <yourpic.pic> call LCDINIT ; Initialize LCD movlw 0x05 call LCDADD movlw 'A' call LCDSEND ; Write character A * ; Variables: d0 equ 0x20 d1 equ 0x21 d2 equ 0x22 LCDTmp equ 0x23
AND IT WORKS, thanks to the author.
Stefan Johansson replies: But it works for me... Anyone else?