;**************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 mr1 equ p2.4 mr2 equ p2.5 ml1 equ p2.6 ml2 equ p2.7 cny70 equ 0x55 ;store sensor's status tdl70 equ 0x54 ;sensor hold delay time s9346_cs equ p1.0 s9346_clk equ p1.1 s9346_di equ p1.2 s9346_do equ p1.3 ;------------------------------------------------ temp_9346 equ 0x75 count_9346 equ 0x74 data_hb equ 0x73 ;data register data_lb equ 0x72 ;data register adrs_9346 equ 0x20 ;single bit define ; ; ;============================================================================== ;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,#13,loop ;判斷是否為Menu鍵 ; Dn_menu: mov dptr,#Dn_scr1 call sho_lcm1 mov dptr,#Dn_scr2 call sho_lcm2 dn_scan: call scan_key mov a,keynum cjne a,#1,dn1 call DCM_menu jmp Dn_menu dn1: cjne a,#2,dn2 call OPS_menu jmp Dn_menu dn2: cjne a,#3,dn3 call MEM_menu jmp Dn_menu dn3: cjne a,#4,dn4 jmp sho_main dn4: jmp dn_scan ;--------------------------------------- jmp $ DCM_menu: mov dptr,#DCM_scr1 call sho_lcm1 mov dptr,#DCM_scr2 call sho_lcm2 DCM_scan: call scan_key mov a,keynum cjne a,#1,d1 call forward jmp DCM_scan d1: cjne a,#2,d2 call back jmp DCM_scan d2: cjne a,#3,d3 call left jmp DCM_scan d3: cjne a,#4,d4 call right jmp DCM_scan d4: cjne a,#0ah,DCM_scan ;判斷是否為Menu鍵 call stop ret OPS_menu: mov dptr,#OPS_scr1 call sho_lcm1 mov dptr,#OPS_scr2 call sho_lcm2 OPS_scan: call scan_y70 call scan_key mov a,keynum cjne a,#0ah,OPS_scan ;判斷是否為Menu鍵 ret MEM_menu: mov dptr,#MEM_scr1 call sho_lcm1 mov dptr,#MEM_scr2 call sho_lcm2 MEM_scan: call scan_key mov a,keynum clr c subb a,#10 jnc m1 call mem_wr jmp MEM_scan m1: mov a,keynum cjne a,#11,m2 call mem_rd jmp MEM_scan m2: cjne a,#0ah,MEM_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 "87654321",0 Dn_scr1: db "1.DCM 2.OPS",0 Dn_scr2: db "3.MEM 4.Return",0 DCM_scr1: db "Walking",0 DCM_scr2: db "",0 OPS_scr1: db "FBLR",0 OPS_scr2: db "",0 MEM_scr1: db "Number",0 MEM_scr2: db "",0 ;============================================================================= mem_wr: call line2 clr s9346_cs ;initial status clr s9346_clk ;initial status clr s9346_di ;initial status setb s9346_do ;;initial status(notice) ; mov adrs_9346,#1 ;write 93c46@00h mov a,keynum add a,#30h mov data_hb,a ;if data high byte=0ah call write_data mov abuf,data_hb call wr_lcddat m3: call scan_key mov a,keynum clr c subb a,#10 jnc m3 mov adrs_9346,#2 ;write 93c46@00h mov a,keynum add a,#30h mov data_hb,a ;if data high byte=0ah call write_data mov abuf,data_hb call wr_lcddat m4: call scan_key mov a,keynum clr c subb a,#10 jnc m4 mov adrs_9346,#3 ;write 93c46@00h mov a,keynum add a,#30h mov data_hb,a ;if data high byte=0ah call write_data mov abuf,data_hb call wr_lcddat m5: call scan_key mov a,keynum clr c subb a,#10 jnc m5 mov adrs_9346,#4 ;write 93c46@00h mov a,keynum add a,#30h mov data_hb,a ;if data high byte=0ah call write_data mov abuf,data_hb call wr_lcddat ret mem_rd: call line2 clr s9346_cs ;initial status clr s9346_clk ;initial status clr s9346_di ;initial status setb s9346_do mov adrs_9346,#1 ;read 93c46@00h call read_data mov abuf,data_hb call wr_lcddat mov adrs_9346,#2 ;read 93c46@00h call read_data mov abuf,data_hb call wr_lcddat mov adrs_9346,#3 ;read 93c46@00h call read_data mov abuf,data_hb call wr_lcddat mov adrs_9346,#4 ;read 93c46@00h call read_data mov abuf,data_hb call wr_lcddat ret clk_pus: setb s9346_clk nop clr s9346_clk ret ;===============write start bit wr_sb: setb s9346_cs setb s9346_di call clk_pus ret ;===============write 1-byte data wr_byte: mov count_9346,#8 wrbit: mov a,temp_9346 rlc a mov temp_9346,a jc wrh clr s9346_di call clk_pus jmp wrlp9346 wrh: setb s9346_di call clk_pus wrlp9346: djnz count_9346,wrbit ret ;===============read 1-byte data rd_byte: mov count_9346,#8 clr a rdbit: call clk_pus jb s9346_do,rdh clr c rlc a jmp rdlp9346 rdh: setb c rlc a rdlp9346: djnz count_9346,rdbit mov temp_9346,a ret ;===============erase/write enable ew_ena: mov temp_9346,#00110000b ;opcode=00,address=11xxxx call wr_sb call wr_byte clr s9346_di clr s9346_cs ret ;==============erase/write disable ew_dis: mov temp_9346,#00000000b ;opcode=00,address=00xxxx call wr_sb call wr_byte clr s9346_di clr s9346_cs ret ;===============erase 1-data,write 0xff to 1-address erase_data: setb adrs_9346.7 ;opcode=11 setb adrs_9346.6 mov temp_9346,adrs_9346 call wr_sb call wr_byte clr s9346_cs clr s9346_di nop setb s9346_cs erasewait: nop jnb s9346_do,erasewait clr s9346_cs ret ;========================================================================= ;***************write 16 bits data to 93c46 write_data: call ew_ena call erase_data clr adrs_9346.7 ;opcode=01 setb adrs_9346.6 mov temp_9346,adrs_9346 call wr_sb call wr_byte nop mov temp_9346,data_hb call wr_byte mov temp_9346,data_lb call wr_byte clr s9346_di clr s9346_cs nop setb s9346_cs wrwait: nop jnb s9346_do,wrwait call ew_dis clr s9346_cs ret ;***************read 16 bits data from 93c46 read_data: setb adrs_9346.7 ;opcode=10 clr adrs_9346.6 mov temp_9346,adrs_9346 call wr_sb call wr_byte nop call rd_byte mov data_hb,temp_9346 call rd_byte mov data_lb,temp_9346 clr s9346_di clr s9346_cs ret scan_y70: mov cny70,#0 ;initial sensor=0 call line2 ;front ;74139=>q0=0 mov pcbit,#6 ;pc6=0 call cl_pc mov pcbit,#7 ;pc7=0 call cl_pc call y70_dl call rd_pb ;read pb,data store at pb55 call data_pro ;data processing ;back ;74139=>q1=0 mov pcbit,#6 ;pc6=1 call st_pc mov pcbit,#7 ;pc7=0 call cl_pc call y70_dl call rd_pb ;read pb,data store at pb55 call data_pro ;data processing ;left ;74139=>q2=0 mov pcbit,#6 ;pc6=0 call cl_pc mov pcbit,#7 ;pc7=1 call st_pc call y70_dl call rd_pb ;read pb,data store to pb55 call data_pro ;data processing ;right ;74139=>q3=0 mov pcbit,#6 ;pc6=1 call st_pc mov pcbit,#7 ;pc7=1 call st_pc call y70_dl call rd_pb ;read pb,data store to pb55 call data_pro ;data processing ; ret ;---------------data processing data_pro: anl pb55,#0f0h ;pb4-pb7 mov a,pb55 ;store to cny70 cjne a,#0xf0,show0 mov abuf,#"1" call wr_lcddat ret show0: mov abuf,#"0" call wr_lcddat ret ;---------------sensor hold delay time y70_dl: mov tdl70,#250 djnz tdl70,$ ret forward: call line2 mov abuf,#"F" call wr_lcddat clr mr1 ;right must inverse setb mr2 setb ml1 ;left is correct clr ml2 ret ;------------car backing--------------- back: call line2 mov abuf,#"B" call wr_lcddat setb mr1 ;right must inverse clr mr2 clr ml1 ;left is correct setb ml2 ret ;------------car lefting--------------- left: call line2 mov abuf,#"L" call wr_lcddat clr mr1 ;right must inverse setb mr2 clr ml1 ;left is correct setb ml2 ret ;------------car righting-------------- right: call line2 mov abuf,#"R" call wr_lcddat setb mr1 ;right must inverse clr mr2 setb ml1 ;left is correct clr ml2 ret ;------------car stop------------------ stop: clr mr1 clr mr2 clr ml1 clr ml2 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