網頁文章 網頁文章

2012/12/18 ;**************combine 8255, keyboard and lcm control program****************
;**************provide this program to students for the second stage test****
;**************Author by 陳君楷***********
;---------------8255 registers define-----------------
ctrl55        equ    0x5f   
pa55        equ    0x5e
pb55        equ    0x5d
pc55        equ    0x5c
pcbit        equ    0x5b
;
a0_8255        equ    p2.0
a1_8255        equ    p2.1
;***************keyboard rigisters define**************
keynum        equ    0x5a            ;keynumber
keydbl        equ    0x59            ;debug bounce,double check
counter        equ    0x58            ;scan keyboard array
bounce0        equ    0x57
bounce1        equ    0x56
key_f        equ     22h.0
;***************lcm rigisters define**************
abuf        equ    0x55            ;the data write to lcm
atmp        equ    0x54            ;the data read from lcm
;
;
;==============================================================================
;LCD_RS========>pc0;LCD_RW========>Pc1
;LCD_En========>pc2;LCD_BUS=======>Pa0-pa7
;data(command,address or data)==>ir(command,address) or dr(data)
;cg rom(192 words),cg ram(8*8 bytes),dd ram(80 bytes)
;first line(0) address=00h->0fh;second line(1) address->40h-4fh
;==============================================================================
        org    00h
Initial:
        mov    ctrl55,#82h        ;8255 initial status setting
        call    wr_ctrl            ;pa:output,pb:input,pc:output
; :::::::  Initial LCD  :::::::
                        ;-------lcm function setting
        mov    abuf,#38h        ; Set for 8 bit data transfer and
        call    wr_lcdcmd        ; address type b,font=5*7
                        ;-------lcm display control
        mov    abuf,#0eh         ; Ture on the display and cursor.
        call    wr_lcdcmd        ; cursor no twinkle
                        ;-------lcm entry model setting
        mov    abuf,#06h         ; Set the LCD unit to increment
        call    wr_lcdcmd        ; the address counter.
;                        ; 20h store in all dd ram address
sho_main:
        mov    dptr,#main_scr1        ; Get the 1st row data(address)
        call    sho_lcm1        ; Call lcm display sub-program2
        mov    dptr,#main_scr2        ; Get the 2nd row data(address)
        call    sho_lcm2        ; Call lcm display sub-program2
;+++++++main program start++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
loop:   
        call    scan_key       
        mov    a,keynum
        cjne    a,#0ah,loop        ;判斷是否為Menu鍵
;
sho_menu:   
        mov    dptr,#menu_scr1
        call    sho_lcm1
        mov    dptr,#menu_scr2
        call    sho_lcm2
looa:   
        call    scan_key       
        mov    a,keynum
        cjne    a,#0ah,looa
;---------------------------------------
        jmp    sho_main
;*******lcm display data sub-program*****************************************************
sho_lcm1:
        call    lcd_cls            ;clear display and cursor return
        call    lcd_printstring
        ret
sho_lcm2:                    ;=======cursor to second line
        clr    a            ;homing to left
        setb    b.0            ;Cursor to second line(1)
        call    lcd_locate        ;b.0=0:line0,b.0=1:line1
        call    lcd_printstring
        ret
;=======display data array====================================================
main_scr1:  db "Welcome",0
main_scr2:  db "9879001",0
menu_scr1: db "1.TS  2.NS ",0
menu_scr2: db "3.NI  4.Return",0
;=============================================================================
lcd_cls:
        mov    abuf, #01h         ;Clear display
        call    wr_lcdcmd
        ret
; ------------------------------------------------
lcd_home:
        mov    abuf, #02h         ;Cursor home
        call    wr_lcdcmd
        ret
; ------------------------------------------------
lcd_locate:
        anl    a, #00001111b        ;00-0fh or 40-4fh
        jnb    b.0,setb7
        setb    acc.6            ;second address 40-4fh
setb7:        setb    acc.7            ;data to ddram not to cgram
        mov    abuf,a
        call    wr_lcdcmd
        ret
; ------------------------------------------------
lcd_printstring:
        clr    a
        movc    a,@a+dptr
        jz    endps            ;if a=0 is endding
        mov    abuf,a
        call    wr_lcddat
        inc    dptr
        jmp    lcd_printstring
endps:        ret
; ------------------------------------------------
lcd_rdpost:
        call    rd_lcdcom
        mov    a,atmp   
        clr    acc.7
        clr    b.0
        jnb    acc.6,notsec        ;40-4fh
        setb    b.0
        clr    acc.6
notsec:        ret
; ------------------------------------------------
wr_lcddat:
        call    chk_lcdbzy
        mov    pcbit,#0        ;lcd_rs=>pc0
        call    st_pc
        mov    pcbit,#1        ;lcd_rw=>pc1
        call    cl_pc
        mov    pcbit,#2        ;lcd_en=>pc2
        call    st_pc
        mov    pa55,abuf        ;lcd data=>pa
        call    wr_pa
        mov    pcbit,#2        ;lcd_en=>pc2
        call    cl_pc
        mov    pcbit,#1        ;lcd_rw=>pc1
        call    st_pc
        mov    pcbit,#0        ;lcd_rs=>pc0
        call    cl_pc
        ret
; ------------------------------------------------
wr_lcdcmd:
        call    chk_lcdbzy
        mov    pcbit,#0        ;lcd_rs=>pc0
        call    cl_pc            ;rs=0->ir
        mov    pcbit,#1        ;lcd_rw=>pc1
        call    cl_pc            ;rw=0->write
        mov    pcbit,#2        ;lcd_en=>pc2
        call    st_pc            ;enable=1   
        mov    pa55,abuf        ;data to pa
        call    wr_pa
        mov    pcbit,#2        ;lcd_en=>pc2
        call    cl_pc
        mov    pcbit,#1        ;lcd_rw=>pc1
        call    st_pc
        mov    pcbit,#0        ;lcd_rs=>pc0
        call    st_pc
        ret
; ------------------------------------------------
rd_lcdcom:
        mov    ctrl55,#92h        ;8255 work status setting
        call    wr_ctrl            ;pa:input,pb:input,pc:output
;
        mov    pcbit,#0        ;lcd_rs=>pc0
        call    cl_pc            ;read ir
        mov    pcbit,#1        ;lcd_rw=>pc1
        call    st_pc            ;read model
        mov    pcbit,#2        ;lcd_en=>pc2
        call    st_pc   
        call    rd_pa
        mov    atmp,pa55
        mov    pcbit,#2        ;lcd_en=>pc2
        call    cl_pc
        mov    pcbit,#1        ;lcd_rw=>pc1
        call    st_pc
        mov    pcbit,#0        ;lcd_rs=>pc0
        call    st_pc
;
        mov    ctrl55,#82h        ;8255 raw status setting
        call    wr_ctrl            ;pa:output,pb:input,pc:output
        ret
; ------------------------------------------------
chk_lcdbzy:
        call    rd_lcdcom
        mov    a,atmp
        jb    acc.7,chk_lcdbzy
        ret
;=================== 82555 control sub-routine ============================
;***************write data to control register
wr_ctrl:                ;ctrl register select=11
        setb    a0_8255
        setb    a1_8255
        mov    a,ctrl55
        movx    @r0,a        ;wr signal
        ret
;***************output data to 8255@pa
wr_pa:                    ;pa register select=00
        clr    a0_8255
        clr    a1_8255
        mov    a,pa55
        movx    @r0,a        ;wr signal
        ret
;**************input data from 8255@pa
rd_pa:                   
        clr    a0_8255        ;pa register select=00
        clr    a1_8255
        movx    a,@r0        ;rd signal
        mov    pa55,a
        ret
;***************input data from 8255@pb
rd_pb:                    ;pb register select=01
        setb    a0_8255
        clr    a1_8255
        movx    a,@r0        ;rd signal
        mov    pb55,a
        ret
;**************output data to 8255@pc by single-bit model
st_pc:                    ;pc register select=10
        setb    a0_8255        ;ctrl register select=11
        setb    a1_8255
        mov    a,pcbit
        setb    c
        rlc    a
        movx    @r0,a        ;wr signal
        ret
;
cl_pc:
        setb    a0_8255        ;ctrl register select=11
        setb    a1_8255
        mov    a,pcbit
        clr    c
        rlc    a
        movx    @r0,a        ;wr signal
        ret
;=============================================================================================
;
scan_key:    mov    keynum,#0    ;key counter=0
        clr    key_f        ;initial
;
;row-0                    ;74139=>q0=0
        mov    pcbit,#4    ;pc4=0
        call    cl_pc
        mov    pcbit,#5    ;pc5=0
        call    cl_pc
        call    rd_pb        ;read pb,data store at pb55
        call    check_key
        jbc    key_f,have_state
;row-1                    ;74139=>q1=0
        mov    pcbit,#4    ;pc4=1
        call    st_pc
        mov    pcbit,#5    ;pc5=0
        call    cl_pc
        call    rd_pb        ;read pb,data store at pb55
        call    check_key
        jbc    key_f,have_state
;row-2                    ;74139=>q2=0
        mov    pcbit,#4    ;pc4=0
        call    cl_pc
        mov    pcbit,#5    ;pc5=1
        call    st_pc
        call    rd_pb        ;read pb,data store to pb55
        call    check_key
        jbc    key_f,have_state
;row-3                    ;74139=>q3=0
        mov    pcbit,#4    ;pc4=1
        call    st_pc
        mov    pcbit,#5    ;pc5=1
        call    st_pc
        call    rd_pb        ;read pb,data store to pb55
        call    check_key
        jbc    key_f,have_state
;
        ret
;
have_state:
        mov    a,keynum
        cjne    a,#0ffh,is_key
is_key:        ret
;***************check key whether true and count key number
check_key:
        anl    pb55,#0x0f    ;pb0-pb3
        mov    a,pb55
        mov    counter,#4
nextk:        rrc    a
        jnc    dblchk
        inc    keynum   
        djnz    counter,nextk
        ret
;
dblchk:        mov    keydbl,pb55
        mov    bounce0,#200    ;about delay time=80mS
chklp:        mov    bounce1,#250
        djnz    bounce1,$
        djnz    bounce0,chklp
        call    rd_pb        ;read pb,data store to pb55
        anl    pb55,#0x0f    ;pb0-pb3
        mov    a,pb55
        cjne    a,keydbl,not_key
        setb    key_f        ;have state
        ret
not_key:    setb    key_f
        mov    keynum,#0ffh    ;not key,is bounce or noise
        ret
;------------------------------------------------------------------
;------------------------------------------------------------------       
        end