; lcd.asm ; tests my 16x2 LCD displays ; Include the header file for our target chip #include "p16f876.inc" ; First line, declare that we want a 16F84 PIC ; and that our numbers will be in Hexadecimal ; unless otherwise noted LIST P=16f876, R=HEX ; Tell the programmer what options we want to use ; In this case: ; _WDT_OFF -- Watchdog Timer Off ; _XT_OSC -- Crystal Oscillator ; _CP_OFF -- Code Protect Off __CONFIG _WDT_OFF & _XT_OSC & _CP_OFF & _LVP_OFF ; Variable Declarations ; Here we assign memory locations for our variables cblock 0x20 delay1 delay2 endc ; See http://www.myke.com/lcd.htm for details of using ; HD44780 LCD displays. #define RS PORTA, 0 #define E PORTA, 1 ; PORTB<4:7> used to send commands in 4-bit mode #define DATA PORTB sdelay macro ; delays for 3*256 cycles = 153.6us local d0 clrf delay1 d0: decfsz delay1,f goto d0 endm Estrobe macro bsf E nop nop nop bcf E endm ; First column is always for labels. Anything in the first ; column will be interpreted by the assembler as a label org 0 goto Start Start CLRF PORTB ; Initialize Port B CLRW ; Clear W register BSF STATUS,RP0 ; Select Register Bank 1 MOVWF TRISB ; Set B to all outputs movwf TRISA ; set A to all outputs movlw 0x06 movwf ADCON1 ; set porta to digital i/o BCF STATUS,RP0 ; select Register Bank 0 call ResetDisplay loop goto loop ClearDisplay: ; Clear the LCD display ; R/S = 0, R/W = 0, DATA1=b'0000', DATA2=b'0001' bcf RS movlw b'00000001' call SendCommand movlw d'100' call delay return SendCommand: ; sends a one-byte command in w to LCD ; assumes RS already set correctly, E cleared movwf DATA Estrobe rlf DATA,f rlf DATA,f rlf DATA,f rlf DATA,f Estrobe sdelay return ResetDisplay: ; Initializes LCD bcf E bcf RS movlw d'100' ; wait 15.4msec call delay movlw 0x3 ; movwf DATA ; send 0x3 out Estrobe movlw d'33' call delay ; wait 5msec Estrobe ; send another 0x3 out sdelay ; wait ~160us Estrobe ; send another 0x3 out sdelay ; wait ~160us movlw 0x28 ; 4 line interface, 2 line display call SendCommand movlw 0x10 ; turn off display call SendCommand call ClearDisplay movlw 0x06 ; set cursor autoincrement call SendCommand movlw 0x0F ; turn on blinking cursor call SendCommand bsf RS movlw 'T' call SendCommand movlw 'e' call SendCommand movlw 's' call SendCommand movlw 't' call SendCommand movlw 'i' call SendCommand movlw 'n' call SendCommand movlw 'g' call SendCommand return delay ; delay for 2+770*w cycles ; at 20MHz that's about 0.154msec*w movwf delay1 clrf delay2 d1: decfsz delay2,f goto d1 decfsz delay1,f goto d1 return END ; End of program