LCD1602网上的资料大多是单片做的,用8086的比较少,主要难点是相关使能位的设置,根据LCD1602的相关使能设置,并将8255作为使能端口。
实现的功能是可以显示一句话,可以设置显示的位置。
通过
mov row,01h;行的位置
mov line,04h;列的位置
lea di,buf4;数据段中的数据位置
mov cl,length4;要显示数据的长度
call show_string;显示过程调用
五句代码可以设置显示的值以及显示的数据。
DATAS SEGMENT
;此处输入数据段代码
MY8255_A dw 0E000H
MY8255_B dw 0E002H
MY8255_C dw 0E004H
MY8255_MODE dw 0E006H
buf1 db 'Floor'
length1 db $-buf1
buf2 db 'Up'
length2 db $-buf2
buf3 db 'Down'
length3 db $-buf3
buf4 db 'Close'
length4 db $-buf4
buf5 db 'Open'
length5 db $-buf5
buf6 db 'Running'
length6 db $-buf6
Row db ?
Line db ?
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
dw 50 dup(?)
top label byte
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
mov ax,stacks
mov ss,ax
mov sp,offset top
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
mov dx,MY8255_MODE
mov al,88h;全为输出,C的高位设置成输入模式
out dx,al
call Lcd_init
restart:
mov row,00h;设置行
mov line,04h;设置列
lea di,buf1
mov cl,length1
call show_string
;--------------------------
mov row,00h
mov line,0bh
lea di,buf2
mov cl,length2
call show_string
;--------------------------
mov row,01h
mov line,04h
lea di,buf4
mov cl,length4
call show_string
;--------------------------
jmp $
Set_cursor proc near
push bx
mov bl,line
mov bh,row
cmp bh,00h
ja row_2;大于说明再第二行
Row_1:
add bl,00h
or bl,80h
mov al,bl
jmp stop
Row_2:
add bl,40h
or bl,80h
mov al,bl
Stop:
pop bx
ret
Set_cursor endp
Show_string proc near;数据在di中,长度在cl中
mov ch,00h
call set_cursor;得到的al的结果即为要显示的数据的位置
call Lcd_wcmd
Loop1:
mov al,[di]
call Lcd_wdata
inc di
loop Loop1
ret
show_string endp
Lcd_init proc near;初始化函数
mov al,38h;16*2显示,5*7点阵,8位数据接口
call Lcd_wcmd
mov al,0ch;显示器开,光标关闭
call Lcd_wcmd
mov al,06h;文字不动,地址自动+1
call Lcd_wcmd
mov al,01h;清屏
call Lcd_wcmd
ret
Lcd_init endp
Lcd_wcmd proc near;写命令函数,把命令存储在al中
call waitready
mov bl,00h;RS和RW都为低电平表示命令模式,输出
call RW_RS_set
mov bl,01h;先需要设置E为低电平
call E_set
mov dx,MY8255_A
out dx,al
mov bl,00h;再设E为高电平
call E_set
ret
Lcd_wcmd endp
Lcd_wdata proc near;写数据函数,把数据存储在al中
call waitready
mov bl,01h;RS=1,RW=0表示数据模式,输出
call RW_RS_set
mov bl,01h;先需要设置E为低电平
call E_set
mov dx,MY8255_A
out dx,al
mov bl,00h;再设E为高电平
call E_set
ret
Lcd_wdata endp
Waitready proc near
push ax
mov dx,MY8255_A;先输出A口为0ffh
mov al,0ffh
out dx,al
mov bl,02h;RS=0,RW=1表示命令模式,输入
call RW_RS_set
Loop1:
mov bl,01h
call E_set
mov dx,MY8255_C;从C口读入命令字
in al,dx
test al,80h;与运算判断输入的第八位是否为1
mov bl,00h
call E_set
jnz loop1;高位为1表示还没有处理完
pop ax
ret
Waitready endp
RW_RS_set proc near;对应PB0,PB1,先把数据存在bl中
;00表示RW=RS=0,01表示RW=0,RS=1,02表示RW=1,RS=0
push ax
mov dx,MY8255_B
mov al,bl
out dx,al
pop ax
ret
RW_RS_set endp
E_set proc near;对应PC4,先把数据存在bl中
push ax
mov dx,MY8255_C
mov al,bl
out dx,al
pop ax
ret
E_set endp
MOV AH,4CH
INT 21H
CODES ENDS
END START