NEW! 416028 |
Another simple Hitachi LCD display control routine. This ASM code can drive a display with a PIC16F628 with the control lines on any PORTB pins - the actual connection are easily redefined in the code by changing the initial definitions.
; LCD driver by Barry (tron at zoidberg dot nl) include p16f628.inc list p=16f628 __config (_CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_CLKOUT & _LVP_OFF & _BODEN_OFF & _MCLRE_OFF) ; LCD control lines #define LCD_RS 5 ; 0 = Command, 1 = Data #define LCD_RW 6 ; 0 = Write, 1 = Read #define LCD_E 4 ; 1 to send data #define LCD_D4 0 ; 4 data lines #define LCD_D5 1 #define LCD_D6 2 #define LCD_D7 3 ; Registers we will be using #define R_DEL1 0x20 ; Delay register #define R_DEL2 0x21 ; Delay register #define R_WDATA_TMP1 0x22 #define R_WDATA_TMP2 0x23 #define R_SEND_W_TMP 0x24 #define R_WTMP 0x27 ; W storage #define R_STMP 0x28 ; STATUS storage #define R_STMP1 0x2E ; Send temp register #define R_PSEC 0x2F org 0 goto init ; Blank interrupt routine - simply saves and restores status & W ; Add code to do something useful... org 4 movwf R_WTMP ; Save W & STATUS swapf STATUS, W movwf R_STMP bcf STATUS, RP0 int_cleanup: movlw b'11111000' ; Clear interrupt bits andwf INTCON, F swapf R_STMP, W ; Restore W & STATUS movwf STATUS swapf R_WTMP, F swapf R_WTMP, W retfie ; Init sets all I/O lines as outputs and selects PORTA as ; I/O lines by turning the comparators off. init: clrf PORTB clrf PORTA movlw 0x07 movwf CMCON ; Comparators off - PORTA on bsf STATUS, RP0 ; Select bank 1 movlw b'00000000' ; Select PORTB as outputs movwf TRISB movlw b'00000000' ; Select PORTA as outputs movwf TRISA bcf STATUS, RP0 ; Select bank 0 ; Begin the LCD initialisation ; Power up timer should give delay, but do it anyway movlw 0x14 call delay ; Send the command to select 4-bit mode first bcf PORTB, LCD_RS bcf PORTB, LCD_RW movlw 0x02 ; Still in 8-bit, so appears as 0x20 to LCD call w_to_data call pulse_e ; Should now be in 4-bit mode - send init movlw b'00101000' call send_w movlw b'00001110' call send_w movlw b'00000110' call send_w main_loop: bcf PORTB, LCD_RS ; Command mode movlw b'00000010' ; Return cursor to home call send_w bsf PORTB, LCD_RS ; Data mode call delay_1ms ; Takes a couple of ms movlw 'H' call send_w movlw 'e' call send_w movlw 'l' call send_w movlw 'l' call send_w movlw 'o' call send_w movlw '!' call send_w goto main_loop ; ---------------------- send_w movwf R_SEND_W_TMP swapf R_SEND_W_TMP, F movlw 0x0F andwf R_SEND_W_TMP, W call w_to_data call pulse_e swapf R_SEND_W_TMP, F movlw 0x0F andwf R_SEND_W_TMP, W call w_to_data call pulse_e return w_to_data movwf R_WDATA_TMP1 movf PORTB, W movwf R_WDATA_TMP2 bcf R_WDATA_TMP2, LCD_D4 bcf R_WDATA_TMP2, LCD_D5 bcf R_WDATA_TMP2, LCD_D6 bcf R_WDATA_TMP2, LCD_D7 btfsc R_WDATA_TMP1, 0 bsf R_WDATA_TMP2, LCD_D4 btfsc R_WDATA_TMP1, 1 bsf R_WDATA_TMP2, LCD_D5 btfsc R_WDATA_TMP1, 2 bsf R_WDATA_TMP2, LCD_D6 btfsc R_WDATA_TMP1, 3 bsf R_WDATA_TMP2, LCD_D7 movf R_WDATA_TMP2, W movwf PORTB return pulse_e bsf PORTB, LCD_E nop nop nop nop bcf PORTB, LCD_E call delay_1ms call delay_1ms return ; Calls the delay_1ms routine the number of times specified by ; the W register. delay movwf R_DEL2 delay_loop call delay_1ms decfsz R_DEL2, F goto delay_loop return ; When called gives a delay of about 1000 cycles, or 1ms at 4Mhz ; before the next instruction is executed. delay_1ms movlw d'248' movwf R_DEL1 delay_1ms_loop nop decfsz R_DEL1, F goto delay_1ms_loop return end
Stephen
van Schalkwyk Says: " I am quite new to
microprocessors and this code is going to be a great help - many thanks!
Stephen "