仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <REGX51.H>
- DIN EQU P3.0
- CLK EQU P3.1
- DBUF EQU 30H
- TEMP EQU 40H
-
- ORG 0000H
- MOV 30H,#00
-
- MAIN: ACALL DISP ;获取段码,并输送给数码显示管
- ACALL KEY ;获取键值
- AJMP MBIN
-
- ;判断键值子程序
- KEY: MOV P1,#0FFH ;初始化
- MOV A,P1 ;P1为按下的键,给累加器A
- CJNE A#0FFH,K00 ;判断是否有键按下,没按就循环,按下就跳到K00
- AJMP KEY
-
- K00: ACALL DELAY ;运行延时子程序,消除抖动操作
- MOV A,P1
- CJNE A,#OFFH,K01 ;二次判断是否按下,没按跳转回KEY
- AJMP KEY1
-
- ;开始判断按下的是那个键
- K01: MOVR3,#9 ;设置判断的循环次数,判断9次,1~9键
- MOV R2,#00H ;设置查表偏移值,从00H开始
- MOV B,A ;A内为按下的值,赋给B,之后做判断使用
- MOV DPTR,#K0TAB ;赋表头地址(键值表(K0TAB))给DPTR
-
- K02: MOV A,R2 ;偏移值赋给累加器A
- MOVC A,@A+DPTR ;偏移值加表头地址得到的键值赋给累加器A
- CJNE AB,K04 ;判断按下的键值和查表的到的键值是否一致,不同则跳转
-
- K03: MOV A,P1
- CJNE A,#0FFH,K03 ;第三次重新判断按下的键
- ACALL DELAY ;延时消除抖动操作
- MOV A,R2 ;偏移值给累加器A?
- RET ;返回
-
- K04: INC R2 ;偏移值加一
- DJNZ R3K02 ;循环次数减一,不等于0,跳转到K02
- MOV A #OFFH ;循环结束,给累加器A赋值FFH
- AJMP KEY ;跳转到KEY,重新开始此子程序
-
- K0TAB: DB 0FFH,0FEH,0FDH,0FBH,0F7H ;键值表
- DB 0EFH,0DFH,0BFH,7FH
-
- DISP: MOV DFUF,A ;段码值给DBUF,A(KEY子程序得到的键码值)给DBUF(30H)
- MOV RO,#DBUF ;30H给R0
- MOV R1,#TEMP ;40H给R1
-
- DP10: MOV DPTR,#SEGTAB ;表头地址给DPTR
- MOV A,@R0 ;((R0))给累加器A,R0=30H
- MOVC A,A+DPTR ;表头地址加累加器A(键码)的值(A=DBUF=30H=键码),查表后得到段码值再给A, (A=段码)
- MOV @R1,A ;上段代码得到的A内的段码给((R1)),((R1))=TEMP=40H,40H=段码值
- MOV RO,#TEMP ;40H再给R0
-
- DP12: MOV R2,#8 ;设置循环次数
- MOV A,@R0 ;段码再给累加器A
-
- DP13: RLC A ;循环左移A(循环左移段码)逐个移动到CY位
- MOV DIN,C ;CY内的值再给DIN,传送到74LS164
- CLR CLK ;清零CLK口
- SETB CLK ;再给CLK口置1
- DJNZ R2.DP13 ;循环减一,循环8次,输送完段码八个位
- RET ;返回主程序
-
- SEGTAB: DB 3FH,06H,5BH,4FH,66H ;段码表
- DB 6DH,7DH,07H,7FH,6FH
-
- DELAY1: MOV R4.#20 ;延时程序,10ms
- AA1: MOV R5,#250
- AA: DJNZ R5,AA
- DJNE R4 AA1
- RET
- END
复制代码
所有资料51hei提供下载:
新建文件夹.rar
(597.3 KB, 下载次数: 39)
|