📄 lcd.asm
字号:
;******************************************************************
;
; Routines to display on a 2x16 character LCD display.
;
; LcdInit - call this subroutine before using the display. It uses
; bits 7-1 of PORTB, leaving bit-0 free (although it will
; be configured as an output).
;
; Lcd_C - Sends the byte in W as a command to the display. Checks
; if busy first.
;
; Lcd_D - Sends the byte in W as data. Checks for busy first.
;
; Assumes it can call a routine called "delay" with a required
; time delay in mSecs in W.
; Uses an additional three (3) levels of the stack.
;
; Address of first line on the LCD is 0
; Address of second line is 64
;
; Ron Kreymborg
;******************************************************************
lcd_com macro arg1
movlw arg1
call lcd_c
endm
; Data -
cblock ; lcd data area
lcd_flags
lcd_temp
endc
; Flags -
lcd_Bflg equ 0
lcd_RSflg equ 1
; I/O portB -
lcd_BUSY equ 7 ; input - LCD is busy (0x80)
lcd_R_W equ 3 ; output - LCD Read/Write (0x08)
lcd_RS equ 2 ; output - Register Select (0x04)
lcd_E equ 1 ; output - LCD Enable (0x02)
lcd_init
clrf PORTB
dotris b'00000000',PORTB ; all outputs and low to start
bcf lcd_flags,lcd_RSflg
dodelay 15 ; 15mSec power up delay
movlw b'00110000' ; 8-bit mode
movwf PORTB
call lcd_clk
dodelay 4 ; 4mSec wait
movlw b'00110000' ; 8-bit mode
movwf PORTB
call lcd_clk
dodelay 1 ; 1 mSec wait
movlw b'00110000' ; 8-bit mode
movwf PORTB
call lcd_clk
dodelay 4 ; 4mSec wait
movlw b'00100000' ; set for 4-bit
movwf PORTB
call lcd_clk
; Reset sequence is done - initialise for us
lcd_com b'00101000' ; 4-bits, 2-lines, 5x7
lcd_com b'00001000' ; display off, cursor off, blink off
lcd_com b'00001100' ; display on
lcd_com b'00000001' ; clear display
lcd_com b'00000110' ; increment, no display shift
return
; Check whether the LCD is busy. Loop until it isn't. When
; it's free, output the byte passed in W, MS nibble first.
lcd_d bsf lcd_flags,lcd_RSflg ; set RS flag for data
goto lcd_o1
lcd_c bcf lcd_flags,lcd_RSflg ; clear RS flag for commands
lcd_o1 movwf lcd_temp ; save control word
dotris b'11110000',PORTB ; RB7-4 as inputs for busy
movlw 1 << lcd_R_W
movwf PORTB ; set up for read
lcd_o2 bcf lcd_flags,lcd_Bflg ; assume not busy
bsf PORTB,lcd_E ; clock high
nop ; little wait
btfsc PORTB,lcd_BUSY ; busy set?
bsf lcd_flags,lcd_Bflg ; yes
bcf PORTB,lcd_E ; clock low
nop ; little wait
nop
call lcd_clk ; get low bits but ignore (for now)
btfsc lcd_flags,lcd_Bflg ; was it busy?
goto lcd_o2 ; yes
dotris b'00000000',PORTB ; RB7-4 outputs again
movf lcd_temp,w ; get word to send
call lcd_o3 ; send high nibble
swapf lcd_temp,w ; get word again
lcd_o3 andlw 0xf0 ; just high bits (clears all control bits)
movwf PORTB
btfsc lcd_flags,lcd_RSflg ; was lcd_RS set?
bsf PORTB,lcd_RS ; yes
call lcd_clk ; write current nibble
return
lcd_clk bsf PORTB,lcd_E ; pulse E line high
nop
bcf PORTB,lcd_E
return
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -