编写程序,利用LED灯亮暗表示按键按下次数(8位二进制数)即按一次加一,汇编语言程序,改用数码管来显示按键次数
时间: 2024-06-11 18:07:06 浏览: 99
这里提供汇编语言程序,使用单片机8051,利用P0口控制LED灯进行计数,再利用P2口控制数码管显示按键次数。其中,使用了外部中断0来检测按键是否按下。
```
; 定义常量
LED equ P0
DIG equ P2
KEY equ P3.2
ORG 0H
; 初始化程序
INIT:
MOV LED, #0FFH ; 初始化LED端口,全部灭掉
MOV DIG, #0FFH ; 初始化数码管端口,全部灭掉
MOV TMOD, #01H ; 定时器0工作方式1,即16位定时器
MOV TH0, #0FDH ; 定时器0计数初值
MOV TL0, #0FDH ; 定时器0计数初值
SETB TR0 ; 启动定时器0
SETB EA ; 打开总中断
SETB ET0 ; 打开定时器0中断
SETB EX0 ; 打开外部中断0
SETB IT0 ; 外部中断0触发方式为下降沿触发
MOV A, #0 ; 初值清零
MOV R0, #0 ; 初值清零
MOV R1, #0 ; 初值清零
MOV R2, #0 ; 初值清零
SJMP MAIN ; 跳转到主程序
; 定时器0中断服务程序
TIMER0_ISR:
CLR TR0 ; 关定时器0
MOV TH0, #0FDH ; 定时器0计数初值
MOV TL0, #0FDH ; 定时器0计数初值
SETB TR0 ; 启动定时器0
DJNZ R2, TIMER0_END ; R2自减,如果不为0则跳过
MOV A, R1 ; R1赋值给A
DEC A ; A自减
MOV R1, A ; A赋值给R1
MOV A, #10 ; A赋值为10
CJNE R1, #0, TIMER0_UPDATE ; 如果R1不为0,则跳转到更新数码管显示
MOV A, #0 ; A赋值为0
MOV R1, A ; A赋值给R1
TIMER0_UPDATE:
MOV R2, #100 ; R2赋值为100
TIMER0_END:
RETI ; 定时器0中断服务程序结束
; 外部中断0服务程序
INT0_ISR:
CPL LED.0 ; LED0亮/灭
INC R0 ; R0自增
RETI ; 外部中断0服务程序结束
; 主程序
MAIN:
MOV R0, #0 ; R0清零
MOV R1, #0 ; R1清零
MOV R2, #100 ; R2赋值为100
LOOP:
MOV DIG, #0FFH ; 数码管全部灭掉
MOV A, R0 ; R0赋值给A
DIV AB, #10 ; A除以10,商在B中,余数在A中
MOV DIG, #0F7H ; 数码管第一个数码管亮
ACALL DIG_SHOW ; 显示余数(个位)
MOV A, B ; 商赋值给A
MOV DIG, #0FBH ; 数码管第二个数码管亮
ACALL DIG_SHOW ; 显示商(十位)
SJMP LOOP ; 循环
; 数码管显示子程序
DIG_SHOW:
ADD A, #48 ; A加上48,转换成ASCII码
MOV P2, A ; 数码管显示
ACALL DELAY_MS ; 延时1ms
MOV P2, #0FFH ; 数码管全部灭掉
ACALL DELAY_MS ; 延时1ms
RET ; 数码管显示子程序结束
; 延时子程序
DELAY_MS:
MOV R4, #1 ; R4赋值为1
MOV R5, #184 ; R5赋值为184
DELAY_LOOP1:
DJNZ R5, $ ; R5自减,如果不为0则跳过
DJNZ R4, DELAY_LOOP1 ; R4自减,如果不为0则跳转到DELAY_LOOP1
RET ; 延时子程序结束
END ; 程序结束
```
需要注意的是,在数码管显示子程序中,使用了延时子程序来延时1ms,以保证数码管显示的稳定性。因为单片机8051的晶振频率一般为11.0592MHz,每个机器周期为12/11.0592≈1.085us,所以需要循环延时约920个机器周期,即约1ms。延时时间可以根据实际需要进行调整。