一、 实验要求
- 掌握数码管显示方法
- 掌握软件延时方法
- 掌握键盘扫描及去抖动方法
二、 实验设计
1.整体思路
使用三个数码管(LED1、LED2、LED3)分别显示计数的个、十、百位。按下K1,计数器加1,按下K2,计数器减1。长按则连续加减。程序通过轮询检测按键状态,实现按键的检测和响应。同时,使用延时函数来处理按键的抖动。
2.流程图
3.主要模块设计思路及分析
模块1: 初始化和显示部分
- ORG 0000H: 程序的起始地址。
- 初始化寄存器和端口,设置共阴极数码管显示。
- ORG 0100H: 程序的入口地址,开始执行主程序。
模块2: 主循环部分(START)
- 使用MOVC指令从数据表(TAB)中获取当前计数值对应的数码管段码。
- 依次处理个、十、百位数,每次显示前先清空上一位的显示。
- 通过移位方式控制数码管的显示,使用P0和P2来控制数码管的位选和段选。
- 每次显示后调用延时函数LCALL D5ms,以控制数码管刷新速度。
模块3: 按键检测部分(UP2)
- 通过轮询方式检测按键状态。
- 如果按键按下,跳转到KEY1处理按键事件。
- 按键的闭合状态通过P3端口读取,通过CPL指令取反,然后与00H比较判断按键是否按下。
模块4: 按键事件处理(KEY1)
- 消除按键抖动,通过延时函数LCALL D10ms实现。
- 重新检测按键状态,确保按键闭合。
- 根据按键状态,跳转到相应的处理模块(ADDI或SUBI)。
模块5: 加法处理(ADDI)
- 逐位加1,包括个位、十位、百位。
- 检查是否需要进位,如果需要,则进位到高位。
模块6: 减法处理(SUBI)
- 逐位减1,包括个位、十位、百位。
- 检查是否需要借位,如果需要,则借位到高位。
模块7: 延时函数(D10ms、D25ms、D5ms)
- 通过嵌套循环实现不同延时时间。
模块8: 数据表(TAB)
- 存储0~9的数码管段码,用于显示对应数字。
三、 实现效果
51电子计数器
四、附录代码:
ORG 0000H
MOV A, #3FH ; 初始化 A,用于共阴极显示
MOV P0, A
MOV R0, #0H
MOV R1, #0H
MOV R2, #0H
ORG 0100H
START: MOV DPTR, #TAB
MOV A, R0
MOVC A, @A+DPTR
MOV P0, #00H ;清空上一位
MOV P2, #11100011B
MOV P0, A
LCALL D5ms
MOV A, R1
MOVC A, @A+DPTR
MOV P0, #00H ;清空上一位
MOV P2, #11100111B
MOV P0, A
LCALL D5ms
MOV A, R2
MOVC A, @A+DPTR
MOV P0, #00H ;清空上一位
MOV P2, #11101011B
MOV P0, A
LCALL D5ms
UP2: MOV P3, #0FFH
MOV A, P3
CPL A
JZ START
CJNE A, #0H, KEY1 ; 比较立即数与寄存器,不相等则转移
SJMP UP2
KEY1: LCALL D10ms ; 非“0”,有按键闭合,延时10ms,消除按键抖动
MOV A, P3
ANL A, #03H
CJNE A, #03H, PK ; 消抖后的重新检测
SJMP UP2
PK: LCALL D25ms
JNB P3.1, ADDI
JNB P3.0, SUBI
LJMP KEY1 ; 调用结束,返回主程序
ADDI: INC R0
MOV A, R0
CJNE A, #10, AddJump1 ; 如果个位数不满 10,则跳过十位的处理
MOV R0, #0H ; 清零个位
INC R1 ; 十位进位
AddJump1:
MOV A,R1
CJNE A, #10, AddJump2 ; 如果十位数不满 10,则跳过
MOV R1,#0H
INC R2
AddJump2:
MOV A,R2
CJNE A, #10, AddJump3 ; 如果百位数不满 10,则跳过
MOV R2,#0H
AddJump3:
LJMP START
RET
SUBI: DEC R0
MOV A,R0
CJNE A, #0FFH,SUBJump1 ;如果个位没有减成负数,就跳过
MOV R0,#09H
DEC R1
SUBJump1:
MOV A,R1
CJNE A, #0FFH,SUBJump2 ;如果十位没有减成负数,就跳过
MOV R1,#09H
DEC R2
SUBJump2:
MOV A,R2
CJNE A, #0FFH,SUBJump3 ;如果百位没有减成负数,就跳过
MOV R2, #0H ;百位减成负数说明我们该进行清空了
MOV R0, #0H ;清空
MOV R1, #0H ;清空
SUBJump3:
LJMP START
RET
D10ms: MOV R7, #25
D1: MOV R6, #200
DJNZ R6, $
DJNZ R7, D1
RET
D25ms: MOV R5,#5
D3: MOV R7,#25
D4: MOV R6,#200
DJNZ R6,$
DJNZ R7,D4
DJNZ R5,D3
RET
D5ms: MOV R7,#12
D2: MOV R6,#200
DJNZ R6,$
DJNZ R7,D2
RET
TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ; 设置 0~9 显示符
END