;**************combine 8255, keyboard and lcm control program**************** ;**************provide this program to students for the second stage test**** ;**************Author by Yu Y.-M. of TEMI. TEL:02-22239560******************* ;---------------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 led_red equ p2.2 led_grn equ p2.3 led_flg equ 21h.1 ;led flag,1=>red,0=>green s74clr equ p1.6 s74clk equ P1.7 s74dta equ P1.0 ;---------------------------- temp_164 equ 0x7f ;display data count_164 equ 0x7e ; ; ;============================================================================== ;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 clr led_flg ;led_flg = 0預設是綠燈 clr led_grn ;設定綠色LED亮 mov a,#0 call numset 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 ;--------------------------------------- scan: call scan_key mov a,keynum cjne a,#01h,s1 ;判斷是否為"1"鍵 call TS_menu jmp sho_menu s1: cjne a,#02h,s2 ;判斷是否為"2"鍵 call NS_menu jmp sho_menu s2: cjne a,#03h,s3 ;判斷是否為"3"鍵 call NI_menu jmp sho_menu s3: cjne a,#04h,s4 ;判斷是否為"4"鍵 jmp sho_main s4: jmp scan ;重新掃描按鍵 jmp $ TS_menu: mov dptr,#TS_scr1 call sho_lcm1 mov dptr,#TS_scr2 call sho_lcm2 call team_set TS_scan: call scan_key mov a,keynum cjne a,#1,t2 call team_set jmp TS_scan t2: cjne a,#0ah,TS_scan ;判斷是否為Menu鍵 ret NS_menu: mov dptr,#NS_scr1 call sho_lcm1 mov dptr,#NS_scr2 call sho_lcm2 NS_scan: call scan_key mov a,keynum clr c subb a,#10 ;減10 jnc n1 ;判斷是否有借位(小於10),如果大於10代表不是按0~9 mov a,keynum ;原來a的值已經改變,要重新載入一次 call numset jmp NS_scan n1: mov a,keynum ;原來a的值已經改變,要重新載入一次 cjne a,#0ah,NS_scan ;判斷是否為Menu鍵 ret NI_menu: mov dptr,#NI_scr1 call sho_lcm1 mov dptr,#NI_scr2 call sho_lcm2 call line2 NI_scan: call scan_key mov a,keynum ;取回按鍵值 clr c subb a,#10 ;將按鍵值減10 jnc nn ;判斷是否有借位(小於10),如果大於10就跳至nn判斷是否是"Menu"鍵 mov a,keynum ;取回按鍵值 add a,#30h ;加上30H,調整成ASCII碼 mov abuf,a call wr_lcddat ;將數字字型顯示於LCD jmp NI_scan nn: mov a,keynum cjne a,#0ah,NI_scan ;判斷是否為Menu鍵 ret ;*******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 line2: ;=======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 ret ;=======display data array==================================================== main_scr1: db "Welcome ",0 main_scr2: db "123456789 ",0 menu_scr1: db "1.TS 2.NS ",0 menu_scr2: db "3.NI 4.Return",0 TS_scr1: db "Team Set ",0 TS_scr2: db " ",0 NS_scr1: db "Number Set ",0 NS_scr2: db " ",0 NI_scr1: db "Number Input ",0 NI_scr2: db " ",0 ;============================================================================= numset: mov dptr,#numcode ;將dptr指到字型表開頭 movc a,@a+dptr ;將所對應的字型複製累加器acc mov temp_164,a ;if number 6:83h,3:boh mov count_164,#8 clr s74clr nop setb s74clr ; next164: mov a,temp_164 rlc a mov temp_164,a ; jc out_h clr s74dta call s164clk jmp loop_164 out_h: setb s74dta call s164clk ; loop_164: djnz count_164,next164 end164: ret ;jmp=>ret ; s164clk: clr s74clk nop setb s74clk ret ; numcode: db 0c0h,0f9h,0a4h,0b0h,99h ;number:0-4 db 92h,82h,0f8h,80h,90h ;number:5-9 team_set: cpl led_flg jb led_flg,red jmp green ; red: clr led_red ;red led setb led_grn ret ;jmp=>ret ; green: ;grn led clr led_grn setb led_red ret ;jmp=>ret 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