;按键控制数码管显示加减
;单片机stc89c52rc 12Mhz
;共阴数码管
;两片74hc573控制8位数码管
SW0 BIT P1.0 ;定义SW0为按键加
SW1 BIT P1.1 ;定义SW1为按键-
D_EN BIT P1.2 ;定义段码锁存端
W_EN BIT P1.3 ;定义位码锁存端
COM EQU P0 ;将P0定义为数据端
SHIWEI EQU 40H ;定义十位存到40h
GEWEI EQU 41H ;定义个位存到41h
BUFFER EQU 42H ;定义缓存区
ORG 0000H ;复位初始化地址
SJMP START ;
ORG 0030H ;
START: ;初始化
MOV SP,60H ;移动堆栈指针
SETB SW0 ;按键+置一
SETB SW1 ;按键-置一
SETB W_EN ;打开位选使能
MOV COM,#0FFH ;让所有的数码管都不选中
CLR W_EN ;关闭位选使能
SETB D_EN ;打开段选使能
MOV COM,#00H ;熄灭所有的数码管
CLR D_EN ;关闭段选使能
CLR BUFFER ;清空缓冲区
MOV DPTR,#TAB ;让DPTR指向显示表列
CLR SHIWEI ;清空十位
CLR GEWEI ;清空个位
MAIN: ;主函数
CALL KEYPORT ;执行按键扫描程序
CALL SHOW ;执行显示程序
SJMP MAIN ;形成主循环
KEYPORT: ;按键子程序
CALL DELAY10_MS ;延时10ms跳过按键抖动区
JNB SW0,JIA ;判断按键+是否按下,按下执行加法程序
JNB SW1,JIAN ;判断按键-是否按下,按下执行减法程序
HUI:RET ;若未按下返回主循环
JIA: ;加法程序
JNB SW0,$ ;判断按键是否释放,未释放pc指针不变
INC BUFFER ;缓冲区数据加1
SJMP HUI ;返回主程序
JIAN: ;减法程序
JNB SW1,$ ;缓冲区数据
DEC BUFFER ;缓冲区数据减1
SJMP HUI ;返回主程序
SHOW: ;显示子程序
MOV A,BUFFER ;将缓冲区数据给累加器a
MOV B,#10 ;给寄存器b赋值10
DIV AB ;执行A/b,结果商(十位)自动存到A,余数(个位)存到b
MOV SHIWEI,A ;将累加器a的十位保存
MOV GEWEI,B ;将寄存器b中的个位保存
;显示十位
MOV A,SHIWEI ;将十位的数据给a
MOVC A,@A+DPTR ;将A+DPTR的结果作为地址找到显示的数据
SETB W_EN ;打开位锁存
MOV COM,#0FEH ;设定显示位
CLR W_EN ;关闭位锁存
SETB D_EN ;打开段锁存
MOV COM,A ;将显示数据给数码管显示
CLR D_EN ;关闭段锁存
CALL DELAY_US ;延时显示
SETB D_EN ;打开段锁存
MOV COM,#00H ;熄灭数码管,消影
CLR D_EN ;关闭段锁存
;显示个位
MOV A,GEWEI ;将个位数据给a
MOVC A,@A+DPTR ;将a+DPTR作为地址找到显示数据
SETB W_EN ;打开位锁存
MOV COM,#0FDH ;设定显示位
CLR W_EN ;关闭位锁存
SETB D_EN ;打开段锁存
MOV COM,A ;将个位数据送到数码管显示
CLR D_EN ;关闭段锁存
CALL DELAY_US ;延时显示
SETB D_EN ;打开段锁存
MOV COM,#00H ;熄灭数码管
CLR D_EN ;关闭段锁存
RET ;返回主程序
DELAY10_MS: ;延时大约10ms,跳过按键抖动区
MOV R7,#50 ;给外层循环赋值50
D0:
MOV R6,#100 ;给内层循环赋值100
DJNZ R6,$ ;R6-- != 0,PC指针不变
DJNZ R7,D0 ;R7-- != 0, 再次进入内层循环
RET ;延时子程序返回按键子程序
DELAY_US: ;设定数码管显示时间
MOV R7,#6 ;给外层循环赋值6
D1:
MOV R6,#100 ;给内层循环赋值100
DJNZ R6,$ ;6-- != 0,PC指针不变
DJNZ R7,D1 ;R7-- != 0, 再次进入内层循环
RET ;返回显示子程序
TAB: ;共阴数码管显示表列0->9
DB 03fH,006H,05bH,04fH,066H
DB 06dH,07dH,007H,07fH,06fH
END ;汇编结束
|