1、单片机原理与应用第2版源代码10中断法查键处理程序设计如下: ORG 0000 LJMP MAIN ORG 0013H LJMP KPINT1MAIN: MOV SP,#6FH SETB IT1 ;选择边沿触发方式 SETB EX1 SETB EA SJMP $KPINT1: PUSH PSW ;中断服务子程序入口 PUSH ACC MOV A,P1 CPL A JZ EXIT ;(A)=0,退出转EXIT LCALL DEL10MS MOV A,P1 CPL A JZ EXIT ;(A)=0,退出转EXITKEY1: CJNE A,#01H,KEY2 LJMP KEYK1 ;是K1键,转入K
2、1键处理子程序KEYK1KEY2: CJNE A,#02H,KEY3 LJMP KEYK2 ;是K2键,转入K2键处理子程序KEYK2KEY3: CJNE A,#04H,KEY4 LJMP KEYK3 ;是K3键,转入K3键处理子程序KEYK3KEY4: CJNE A,#08H,KEY5 LJMP KEYK4 ;是K4键,转入K4键处理子程序KEYK4KEY5: CJNE A,#10H,KEY6 LJMP KEYK5 ;是K5键,转入K5键处理子程序KEYK5KEY6: CJNE A,#12H,KEY7 LJMP KEYK6 ;是K6键,转入K6键处理子程序KEYK6KEY7: CJNE A,
3、#14H,KEY8 LJMP KEYK7 ;是K7键,转入K7键处理子程序KEYK7KEY8: CJNE A,#18H,EXIT LJMP KEYK8 ;是K8键,转入K8键处理子程序KEYK8EXIT: RETIDEL10MS: MOV 60H,#10 ;延时10 ms子程序,晶振6 MHzLP1: MOV 61H,#250 DJNZ 61H,$ DJNZ 60H,LP1 RET END针对图10-5编程时,要求只处理单一按键,如有两个或多个按键同时按下视为无效,不予以处理,单片机应定时查询数据总线P0端口,按键采用延时去抖。按键处理程序设计如下:KEY_IN: MOV DPTR,#7FFF
4、H MOVX A,DPTR ;读按键值 ANL A,#1FH ;屏蔽高3位 CJNE A,#1FH,KEYQD ;判断是否有键按下 LJMP EXIT ;无键按下,退出键盘扫描KEYQD: LCALL DEL10MS ;有键按下,延时10 ms去抖 MOVX A,DPTR ;再读按键值 ANL A,#1FH CJNE A,#1FH,KEY1 LJMP EXITKEY1: CJNE A,#1EH,KEY2 LJMP KEYK1 ;是K1键,转入K1键处理子程序KEYK1KEY2: CJNE A,#1DH,KEY3 LJMP KEYK2 ;是K2键,转入K2键处理子程序KEYK2KEY3: CJN
5、E A,#1BH,KEY4 LJMP KEYK3 ;是K3键,转入K3键处理子程序KEYK3KEY4: CJNE A,#17H,KEY5 LJMP KEYK4 ;是K4键,转入K4键处理子程序KEYK4KEY5: CJNE A,#0FH,EXIT LJMP KEYK5 ;是K5键,转入K5键处理子程序KEYK5EXIT: RETDEL10MS: MOV 60H,#10 ;延时10 ms子程序,晶振为6 MHzLP1: MOV 61H,#250 DJNZ 61H,$ DJNZ 60H,LP1 RET 在行扫描法中,将所有行线作为输出端口,并逐行输出低电平,将所有列线作为输入端口,得到行、列线值后
6、,也可以不采用查表的方式查找键码。下面这个行扫描法查键程序,采用了非查表法,比较巧妙地找到按键键码,查键处理程序设计如下:KEY_IN: MOV P1,#0F0H ;P1端口低4位全部输出0电平 MOV A,P1 ;从P1端口高4位读入列信号 ORL A,#0FH ;屏蔽低4位 CPL A ;取反 JZ KPEXT ;没有按键,即若A=0,Z=1,跳转到KPEXT MOV R4,#0 ;键值初始化 MOV R2,#0FEH ;行扫描码初始化 MOV R7,#4 ;扫描次数(行线数)KP1: MOV P1, R2 ;从P1端口低4位输出扫描码 MOV A,P1 ;从P1端口高4位读入列信息 OR
7、L A,#0FH ;屏蔽低4位 CPL A ;取反 JNZ KP2 ;本行有按键被按下否?若有键,跳转到KP2 MOV A,R4 ;计算下一行键的起始键值 ADD A,#4 MOV R4,A MOV A,R2 ;计算下一行的扫描码 RL A MOV R2,A DJNZ R7,KP1 ;全部扫描结束否 SJMP KPEXT ;无按键操作KP2: JB ACC.4,KP3 ;是否第一列(若ACC.4=1,即为第一列有键) RR A ;调整到下一列 INC R4 ;调整键码 SJMP KP2 ;继续判断KP3: MOV A,R4 ;取键码,即键值 RET ;返回键码KPEXT: MOV A,#0FF
8、H ;没有按键操作,返回0FFH RET线反转法查键及键码转换处理程序设计如下:KEY_IN: MOV P1,#0F0H ;行线低4位输出低电平 MOV A,P1 ;从高4位读取列线值 ANL A,#0F0H ;屏蔽低4位获得列线值 MOV B,A ;暂存列线值B MOV P1,#0FH ;列线高4位输出低电平 MOV A,P1 ;从低4位读取行线值 ANL A,#0FH ;屏蔽高4位获得行线值 ORL A,B ;行、列值合并,得到按键特征码 CJNE A,#0FFH,KPIN1 ;判断有按键否 AJMP EXIT ;与0FFH相等,无按键,返回KPIN1: MOV B,A ;有按键,把特征码
9、暂存B MOV DPTR,#TABKP ;DPTR指向键码表首地址 MOV R3,#0 ;顺序码初始化KPIN2: MOV A,R3 ;按顺序码查表 MOVC A,A+DPTR ;按顺序码查表 CJNE A,B,KPIN3 ;按键特征码与查表特征码比较 MOV A,R3 ;相等,顺序码有效,得到键码A AJMP EXIT ;返回对应的键码(A)KPIN3: INC R3 ;不相等,调整顺序码,准备查下一个 CJNE A,#0FFH,KPIN2 ;是否为表格结束标志EXIT: RET ;查到表格末尾仍未找到,以无按键处理TABKP: DB 0EEH,0DEH,0BEH,7EH ;K0到K3的特征
10、码 DB 0EDH,0DDH,0BDH,7DH ;K4到K7的特征码 DB 0EBH,0DBH,0BBH,7BH ;K8到KB的特征码 DB 0E7H,0D7H,0B7H,77H ;KC到KF的特征码 DB 67H,0FFH ;KC+KF的特征码和表格结束标志下面是静态显示3位50H52H中的数的子程序:DISP: MOV R2,#03 MOV R0,#50HLP0: MOV A,R0 ADD A,#0BH MOVC A,A+PC MOV SBUF,ALP1: JNB TI,LP1 CLR TI INC R0 DJNZ R2,LP0 RETTAB: DB 03H,9FH,25H,0DH,99H
11、,49H ;笔形码表09 DB 41H,1FH,01H,09H,0FFH,0FFH动态显示程序设计如下:DISP: MOV R3,#00 ;显示初值为0 MOV R4,#0E8H ;循环显示次数 MOV DPTR,#TAB ;置笔形码表首地址LP0: MOV A,R3 MOVC A,A+DPTR MOV P1,A ;送显示段选码 SETB P2.2 ;控制输出锁存 CLR P2.2 ;保存输出DELAY: ACALL DISP1 DJNZ R4,DELAY INC R3 CJNE R3,#0AH,LP0 ;控制显示一遍09数字 AJMP EXQDISP1: MOV R1,#04 MOV R5,
12、#00DISP2: MOV A,R5 MOV P2,A ;送位选码 ACALL DEL1 ;每位显示1 ms INC R5 ;指向下一个LED DJNZ R1,DISP2 ;未显示完4位继续 RETDEL1: MOV R6,#250 ;延时1 ms(6 MHz晶振)LP2: DJNZ R6,LP2EXQ: RETTAB: DB 0C0H,0F9H,0A4H,0B0H,99H ;09数字共阳笔形码 DB 92H,82H,0F8H,80H,90H按照图10-17电路,编写显示参考程序段如下:EN EQU P1.2CLK EQU P1.0DIN EQU P1.1DISP: CLR CLK CLR E
13、N MOV R7,#60DEL: DJNZ R7,DEL ;延时 MOV R7,#04 ;控制写入4位 MOV A,#4FH ;小数点送A(高4位),即点亮第2位的小数点 ACALL WRD MOV A,R0 ;读取显示的BCD码A MOV R7,#08 ;控制写入8位 ACALL WRD DEC R0 MOV A,R0 MOV R7,#08 ACALL WRD SETB EN RETWRD: SETB CLK ;写入n个二进制位子程序 RLC A MOV DIN,C CLR CLK DJNZ R7,WRD RET单片机与MAX7219的通信程序设计如下:DIN EQU P1.0 ;定义数据线
14、LOAD EQU P1.1 ;定义装载线CLK EQU P1.2 ;定义时钟线 ORG 0000 LJMP MAIN ORG 0030HMAIN: ACALL INITDISP: MOV R0,#30H ;置显示缓冲区起始地址(存储显示数BCD码) MOV R1,#01 MOV R3,#08LOOP3: MOV A,R0 MOV R4,A MOV A,R1 ACALL WRITE ;调用写8位数据子程序 INC R0 INC R1 DJNZ R3,LOOP3 LJMP DISPWRITE: MOV R2,#08 CLR LOAD ;LOAD引脚置低 SETB LOAD ;LOAD引脚置高LOO
15、P1: CLR CLK ;CLK引脚置低 RLC A ;移位传送位控数据 MOV DIN,C CLR CLK SETB CLK DJNZ R2,LOOP1 MOV A,R4 MOV R2,#08LOOP2: CLR CLK RLC A ;移位传送段码数据 MOV DIN,C CLR CLK SETB CLK DJNZ R2,LOOP2 CLR LOAD SETB LOAD RET以下是MAX7219控制寄存器初始化子程序:INIT: MOV A,#09H ;置译码方式 MOV R4,#0FFH ACALL WRITE MOV A,#0AH ;置亮度控制 MOV R4,#08 ACALL WRI
16、TE MOV A,#0BH ;置扫描界线 MOV R4,#07 ACALL WRITE MOV A,#0CH ;置掉电控制 MOV R4,#01 ACALL WRITE RETDELAY: MOV R7,#0 ;延时程序AA: NOP NOP DJNZ R7,AA RET假设需要显示的数据已经分离出并存储在30H35H单元,则程序段如下:P1.0 bit CLKP1.1 bit SKY1P1.2 bit SKY2P1.3 bit SKY3DISP: SETB CLK ;CLK=1,允许TXD引脚同步移位脉冲输出显示 MOV R7,#06H ;循环次数控制 MOV R0,#30H ;R0作为显示
17、数据指针DSP1: MOV A,R0 ;取显示数送A ADD A,#0DH ;加偏移量 MOVC A,A+PC ;查表取笔形码 MOV SBUF,A ;将段码送SBUF JNB TI,$ ;输出段码,查询TI状态,1字节的段码输出完否 CLR TI ;1字节的段码输出完,清TI标志 INC R0 ;指向下一个显示数据单元 DJNZ R7,DSP1 ;段码个数计数器R7是否为0,若不为0,转DSP1继续 CLR CLK ;CLK=0,禁止TXD输出同步移位脉冲到显示器 RETTAB1: DB 03H,9FH,25H,0DH,99H, ;共阳极段码表,对应0,1,2,3,4 DB 49H,41H,
18、1FH,01H,09H ;5,6,7,8,9 DB 11H,0C1H,63H,85H,61H ;A,B,C,D,E DB 71H,0FDH,31H,0FFH,0FFH ;F,P,暗 以下是键盘扫描子程序段:KEY_IN: CLR CLK ;清CLK=0,禁止串口移位输出显示 MOV A,#00H ;准备逐列扫描判键 MOV SBUF,A ;向74LS164(7)输出00H,使所有列线为低电平 JNB TI,$ CLR TI KNO: JNB SKY1,KDY ;判第1行是否有按键,如有按键跳转KDY JNB SKY2,KDY ;判第2行是否有按键,如有按键跳转KDY JB SKY3,KNO ;
19、判第3行是否有按键,无按键跳转KNOKDY: ACALL DELY ;软件去抖,调用延时10 ms子程序 JNB SKY1,KIN1 ;判断是否抖动引起的 JNB SKY2,KIN1 JB SKY3,KNOKIN1: MOV R7,#08H ;逐列扫描次数 MOV R6,#0FEH ;先扫描第1列(列代码FEH),使QA=0 MOV R3,#00H ;R3为列号寄存器 MOV A,R6KIN3: MOV SBUF,A ;从串行口输出列代码 JNB TI,$ CLR TI JNB SKY1,KIN2 ;判第1行是否有按键,如有按键跳转KIN2 JNB SKY2,KIN5 ;判第2行是否有按键,如
20、有按键跳转KIN5 JB SKY3,NEXT ;判第3行是否有按键,如无按键跳转NEXT MOV R4,#10H ;第3行行首键号10H送入R4 AJMP PK3KIN5: MOV R4,#08H ;第2行行首键号08H送入R4 AJMP PK3KIN2: MOV R4,#00H ;第1行行首键号00H送入R4PK3: MOV SBUF,#00H ;等待松键,发送00H使所有列线为低电平 JNB TI,$ CLR TIKIN4: JNB SKY1,KIN4 ;判行线状态 JNB SKY2,KIN4 JNB SKY3,KIN4 MOV A,R4 ;两行线均为高电平,表示键已松开 ADD A,R3
21、 ;行号+列号可得到键码A RET ;找到键码,返回NEXT: MOV A,R6 ;列扫描码左移一位,判断下列键 RL A MOV R6,A ;记列扫描码于R6中 INC R3 ;列号加1 DJNZ R7,KIN3 ;判断是否扫描完8列 RET ;8列已扫描完毕返回DELY: MOV R7,#0AH ;延时10ms子程序(晶振6MHz)DL1: MOV R6,#250 DJNZ R6,$ DJNZ R7,DL1 RET按照图10-22电路连接编程,将扫描得到的按键值送出显示。程序设计如下:SDA BIT P1.0 ;I2C总线定义 SCL BIT P1.1ACK BIT 00H ;应答信号标志
22、位MTD DATA 30H ;发送缓冲区(30H37H)MRD DATA 38H ;接收缓冲区(38H3FH)SLA DATA 40H ;器件从地址SUBA DATA 41H ;器件子地址NUMBYTE DATA 42H ;数据传输字节数DISP_BUF DATA 43H ;存储显示数据的缓冲区首地址(43H4AH)DISP_NUM DATA 4BH ;数码显示个数CMD0 DATA 4CH ;命令1CMD1 DATA 4DH ;命令2ADDR DATA 4EH ;ZLG7290内部寄存器地址DATA0 DATA 4FH ;写入ZLG7290内部寄存器的数据存储单元BUF DATA 50H ;
23、显示缓冲区的指针ZLG7290 EQU 70H ;ZLG7290的器件地址SUBCMD EQU 07H ;ZLG7290的命令缓冲区地址SUBKEY EQU 01H ;ZLG7290的键值寄存器地址 ORG 0000H ;主程序 LJMP MAINMAIN: MOV SP,#60H MOV DISP_BUF,#01 MOV DISP_BUF+1,#02 MOV DISP_BUF+2,#03 MOV DISP_BUF+3,#04 MOV DISP_NUM,#04 LCALL DISPLY LOOP: LCALL GET_KEY MOV A,MRD JZ LOOP MOV B,#10H DIV A
24、B MOV DISP_BUF,A MOV DISP_BUF+1,B MOV DISP_NUM,#02 LCALL DISPLY LJMP LOOPDISPLY: MOV BUF,#DISP_BUF ;ZLG7290送显示命令子程序 MOV R7,DISP_NUM MOV CMD0,#60H ;显示命令字(从0位置开始显示)DISP1: MOV R0,BUF MOV CMD1,R0 ;读取显示数据 LCALL SEND_CMD INC BUF INC CMD0 DJNZ R7,DISP1 RETWR_RGE: MOV SLA,#ZLG7290 ;ZLG7290写寄存器子程序 MOV SUBA,A
25、DDR MOV MTD,DATA0 MOV NUMBYTE,#01 LCALL IWRNBYTE ;调用数据写入子程序 LCALL DEL10MS RETSEND_CMD: MOV SLA,#ZLG7290 ;ZLG7290发送控制命令子程序 MOV SUBA,#SUBCMD MOV MTD,CMD0 MOV MTD+1,CMD1 MOV NUMBYTE,#02 LCALL IWRNBYTE ;调用数据写入子程序 LCALL DEL10MS RETGET_KEY: MOV SLA,#ZLG7290 ;ZLG7290读键值子程序 MOV SUBA,#SUBKEY MOV NUMBYTE,#01 LCALL IRDNBYTE ;调用数据读出子程序DEL10MS: MOV 51H,#4DEL_B: MOV 52H,#123 DJNZ 52H,$ DJNZ 51H,DEL_B RETIWRNBYTE: MOV A,NUMBYTE ;向器件指定子地址写入N字节子程序 MOV R3,A LCALL START ;启动总线,见9.5.4节的I2C总线常用子程序 MOV A,SLA LCALL WRBYTE ;发送器件从地址(参考I2C
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1