Zde najdete odpověď na neustále se opakující dotaz: "Jak připojit znakový LCD displej k MCS51". Jedná se o základní zapojení v 8-bitovém režimu k I/O portu procesoru. Možností připojení je samozřejmě více: čtyřbitový režim, připojení do adresního prostoru, připojení prostřednictvím I2C expanderu a řada dalších.


RS_LCD         EQU     P3.7            ; instruct or data command LCD
RW_LCD         EQU     P3.0            ; read or write command LCD
CS_LCD         EQU     P3.1            ; chip select LCD
DATA_BUS       EQU     P1              ; 8 bit data bus

               ORG     0

main:           call    initialize
                mov     a,#0            ; set cursor to addr 0
                acall   goto_lcd
                mov     dptr,#str1      ; string 1
                acall   put_str
                mov     a,#40h          ; set curser to addr 40h
                acall   goto_lcd
                mov     dptr,#str2      ; string 2
                acall   put_str
                sjmp    $

initialize:     call    init_lcd        ; Initial LCD
                ret

                ;initialize character LCD ,5*7 dot,4 line

init_lcd:       mov     a,#15           ; delay 15 ms when power on
                acall   delay_ms

                mov     a,#38h          ; function set
                acall   write_ins_lcd
                mov     a,#5            ; delay 5 ms when power on
                acall   delay_ms

                mov     a,#38h          ; function set
                acall   write_ins_lcd
                mov     a,#1            ; delay 1 ms when power on
                acall   delay_ms

                mov     a,#38h          ; function set
                acall   write_ins_lcd
                acall   busy_lcd

                mov     a,#38h          ; function set
                acall   write_ins_lcd
                acall   busy_lcd

                mov     a,#0ch          ; display on/off
                acall   write_ins_lcd
                acall   busy_lcd

                mov     a,#06h          ; entry mode set
                acall   write_ins_lcd
                acall   busy_lcd

                acall   clr_lcd         ; clr display
                ret


                ; Write ADCII to LCD the value in the accumulator.

write_lcd:      push    acc
                setb    RS_LCD          ; data reg. (DR)
                clr     RW_LCD          ; write data
                setb    CS_LCD          ; enable strobe

                mov     DATA_BUS,acc    ; write data
                clr     CS_LCD          ; disable LCD
                acall   delay_40us      ; wait for excution time 40 uS

                acall   busy_lcd        ; chack busy
                pop     acc
                ret

                ; Read busy flag LCD

busy_lcd:       clr     RS_LCD          ; instruction reg. (IR)
                setb    RW_LCD          ; read data
                setb    CS_LCD          ; eanble strobe

wait_bl:        mov     a,#0ffh         ; clear data bus
                mov     a,DATA_BUS      ; read command
                jb      acc.7,wait_bl   ; wait BF flag is clr
                clr     CS_LCD          ; disable LCD
                ret                    
               
                ; clear display and set DD ram address 0

clr_lcd:        mov     a,#1            ; clear command
                acall   write_ins_lcd   ; write instruct
                mov     a,#2            ; delay 2 mS
                acall   delay_ms
                acall   busy_lcd        ; chack busy                
                ret                    
               
                ; cursor on

cur_on:         mov     a,#00fh         ; D=1, C=1, B=1;
                acall   write_ins_lcd   ; write instruct

                mov     a,#2            ; delay 2 mS                
                acall   delay_ms
                acall   busy_lcd        ; check busy                
                ret                    
               
                ; cursor on
               
cur_off:        mov     a,#00ch         ; D=1, C=1, B=1;                
                acall   write_ins_lcd   ; write instruct
                mov     a,#2            ; delay 2 mS                
                acall   delay_ms
                acall   busy_lcd        ; check busy                
                ret
               
                ; set DD ram address 0
               
return_home_lcd:mov     a,#2            ; return home command                
                acall   write_ins_lcd   ; write instruct
               
                mov     a,#2            ; delay 2 mS                
                acall   delay_ms
               
                acall   busy_lcd        ; check busy                
                ret
               
                ; set DD ram address the value in the accumulator.
               
goto_lcd:       setb    acc.7           ; set DD ram command
                acall   write_ins_lcd   ; write instruct
                acall   delay_40us      ; wait for excution time 40 uS
               
                acall   busy_lcd        ; check busy                
                ret
               
write_ins_lcd:  clr     RS_LCD          ; instruction reg. (IR)
                clr     RW_LCD          ; write data                
                setb    CS_LCD          ; eanble strobe
               
                mov     DATA_BUS,acc    ; write commnad                
                clr     CS_LCD          ; disable LCD                
                ret
               
                ; Delay for one mS times the value in the accumulator. X'TAL 12 MHz
               
delay_ms:       push    acc             ; 2 uS                
                push    b               ; 2 uS
               
                mov     b,#241          ; 2 uSdm:            
                djnz    b,$             ; 2 uS ,248 * 2 = 496                
                mov     b,#249          ; 2 uS                
                djnz    b,$             ; 2 uS ,249 * 2 = 498                
                mov     b,#248          ; 2 uS                
                djnz    acc,dm          ; 2 uS
               
                pop     b               ; 2 uS                
                pop     acc             ; 2 uS
               
                ret                     ; 2 uS
               
                ; Delay for 40 uS timers the value in the accumulator. X'TAL 12 MHz
               
delay_40us:     push    acc             ; 2 uS
                mov     a,#15           ; 2 uS
               
                djnz    acc,$           ; 2 uS ,15 * 2 = 30
               
                pop     acc             ; 2 uS                
                ret                     ; 2 uS
               
                ; Write LCD in program momory
                ; Input dptr = data pointer
               
put_str:        acall   goto_lcd

put_str1:       clr     a               ; clear accumulator
                movc    a,@a+dptr       ; get charecter into accumulator                
                jz      end_put_str     ; jump if charecter is end of file (00h)                
                acall   write_lcd       ; put charecter to LCD                
                inc     dptr                
                sjmp    put_str1        ; next charecter
               
end_put_str:    inc     dptr                
                ret
               
str1:           DB      "* Test LCD *",0str2:          
                DB      "www.mcu.cz",0
                END