LIST P=18F2550 ;directive to define processor #include ;processor specific variable definitions ; XTAL = 20 MHz ; Oscillator Selection: CONFIG FOSC = XT_XT ;XT oscillator, XT used by USB ; Variable definitions CBLOCK 0x0000 d1 d2 d3 scomm sdata TEMP TEMP2 ENDC ; RESET VECTOR ORG 0x0000 goto init init: CLRF PORTB CLRF LATB MOVLW h'0E' ; Switch AN = OFF MOVWF ADCON1 ; MOVLW h'00' ; all PORTB = OUTPUT MOVWF TRISB #define DB4 PORTB, RB0 #define DB5 PORTB, RB1 #define DB6 PORTB, RB2 #define DB7 PORTB, RB3 #define RS PORTB, RB4 #define RW PORTB, RB5 #define E PORTB, RB6 main: CALL lcd_init CALL delay_30ms MOVLW 'A' CALL lcd_senddata STOPIT GOTO STOPIT ; so we have no conflict with the rest of the code lcd_init ; yes i know what you think ;-), we need 250 mS and i am too lazy to write a bigger Delay Routine CALL delay_30ms ; 250 mS Pause for internal LCD POR CALL delay_30ms ; 250 mS Pause for internal LCD POR CALL delay_30ms ; 250 mS Pause for internal LCD POR CALL delay_30ms ; 250 mS Pause for internal LCD POR CALL delay_30ms ; 250 mS Pause for internal LCD POR CALL delay_30ms ; 250 mS Pause for internal LCD POR CALL delay_30ms ; 250 mS Pause for internal LCD POR CALL delay_30ms ; 250 mS Pause for internal LCD POR CALL delay_30ms ; 250 mS Pause for internal LCD POR CALL delay_30ms ; 250 mS Pause for internal LCD POR ; MOVLW b'00000011' ; MOVWF PORTB ;initialize display interface to 8bit (1) ; CALL lcd_enable ; CALL delay_30ms ; MOVLW b'00000011' ; MOVWF PORTB ;initialize display interface to 8bit (1) ; CALL lcd_enable ; CALL delay_30ms ; MOVLW b'00000011' ; MOVWF PORTB ;initialize display interface to 8bit (1) ; CALL lcd_enable ; CALL delay_30ms ; CALL lcd_enable ;initialize display interface to 8bit (2) ; CALL delay_30ms ; CALL lcd_enable ;initialize display interface to 8bit (3) ; CALL delay_30ms ; 4 Bit Enable for your I/O Hardware (Low Nibble PortB) MOVLW b'00000010' MOVWF PORTB ;initialize display interface to 4bit CALL lcd_enable CALL delay_30ms ; Full 8 Bit Command via lcd Routine MOVLW b'00000001' ; Clear display, Cursor Home CALL lcd_sendcommand CALL delay_30ms MOVLW b'00101000' ; 2 rows, 4 BIT, 5x7 Character CALL lcd_sendcommand CALL delay_30ms MOVLW b'00001000' ; Display off CALL lcd_sendcommand CALL delay_30ms MOVLW b'00000110' ;Cursor right, no shift CALL lcd_sendcommand CALL delay_30ms MOVLW b'00000011' ; Cursor Home CALL lcd_sendcommand CALL delay_30ms MOVLW b'00001111' ; Display on CALL lcd_sendcommand CALL delay_30ms RETURN ; that was missing OMG lcd_enable BSF E NOP NOP BCF E RETURN lcd_sendcommand BCF RS MOVWF scomm MOVLW b'11110000' ANDWF scomm, 0 MOVWF TEMP ;swap nibbles to fit on the I/O SWAPF TEMP, 1 MOVF PORTB, 0 ;read PORTB MOVWF TEMP2 MOVLW b'11110000' ANDWF TEMP2, 1 MOVF TEMP2, 0 ADDWF TEMP, 0 MOVWF PORTB CALL lcd_enable MOVLW b'00001111' ANDWF scomm, 0 ADDWF TEMP2, 0 MOVWF PORTB CALL lcd_enable CALL delay_100us RETURN lcd_senddata BSF RS MOVWF sdata MOVLW b'11110000' ANDWF sdata, 0 MOVWF TEMP SWAPF TEMP, 1 MOVF PORTB, 0 MOVWF TEMP2 MOVLW b'11110000' ANDWF TEMP2, 1 MOVF TEMP2, 0 ADDWF TEMP, 0 MOVWF PORTB CALL lcd_enable MOVLW b'00001111' ANDWF sdata, 0 ADDWF TEMP2, 0 MOVWF PORTB CALL lcd_enable CALL delay_100us RETURN ;---------------------------------------------------------------------------- ;|Delay subroutines ; ; ; ;---------------------------------------------------------------------------- ; 30,6392 mS but it is not critical to do a bit more delay_30ms ;89993 cycles movlw d'150' ; 0x5E d'94' movwf d1 movlw d'120' ; 0x47 d'71' movwf d2 delay_30ms_0 decfsz d1, f goto L1 decfsz d2, f L1 goto delay_30ms_0 ;3 cycles nop nop ;4 cycles (including call) return ; 145,8 uS delay_100us ;295 cycles movlw 0xF2 movwf d1 delay_100us_0 decfsz d1, f goto delay_100us_0 ;1 cycle nop ;4 cycles (including call) return END