51单片机基于定时器中断的60s计时器

1、7447芯片介绍

抽象化芯片功能,先介绍一下用于数码管显示的7447芯片和整个硬件电路,有利于建立对整个系统的理解。

数码管介绍移步:51单片机七段式数码管显示

7447芯片是一块将BCD码转换成7段LED数码管段码的译码驱动IC,7447的主要功能是输出低电平驱动的显示码,用以推动共阳极7段LED数码管显示相应的数字。

BCD码(Binary-Coded Decimal‎),用4位二进制数来表示1位十进制数中的0~9这10个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码。

如果直接将想显示的不大于60D(3CH)的数赋给P1口,数码管会显示异常。这是因为7447芯片和数码管接收的是二进制数据,我们将4位2进制数看作是一个10进制数,这样的话1010-1111是无效的,7447芯片也无法传递正确的段码。

也就是说,当想显示的数高位或低位处于1010-1111时,数码管无法显示正确的数字。

想正确显示十进制数,需要将P1口输出的二进制数分为2x4位,分别代表十位和个位经过7447芯片传输给各自的数码管,可以用数模转换的方法将数值转为数码管可以理解并正常运行的模拟量。

2、 程序介绍

通过定时器中断实现1s计时,计满60s后切换LED灯显示状态,循环往复

3、代码介绍

(1)单片机程序入口
51单片机上电复位后‌从00H开始执行‌,因此必须在该地址放置第一条有效指令,避开中断向量区,防止程序跑飞。

ORG 00H
    JMP START 

 (2)初始化程序

定时器定时50ms执行20次即为定时1s,每定时1s记录一次次数,当记满60次将连接LED灯的P0.7口取反实现LED显示状态切换。利用懒汉程序触发中断器,提高程序扩展性和可读性。

START:MOV TMOD,#11H                ;首先设置定时器模式和中断使能寄存器
    MOV IE,#10000010B     

  

;初始化程序
    MOV P0,#0        ;点亮LED灯
    MOV R0,#0        ;计秒并赋值给A,对A数模转换
    MOV R6,#20        ;定时20次50ms=1s
    MOV R7,#60        ;定时60次1s=60s
    CALL DISP        ;为R0赋初值后调用数码管显示子程序,令数码管显示0
    CLR TR0        ;使用计时器,确保进入懒汉程序后能够触发中断
    MOV TH0,#HIGH(15536)
    MOV TL0,#LOW(15536)
    SETB TR0

REQUEST:SJMP $        ;懒汉程序,等待中断触发后开始计秒

不直接用A计秒是因为数模转换后不能再重新用于计秒,显示会出错。 

(3)定时器中断

T0计满后自动执行CALL 0BH,进入中断

利用DJNZ指令执行R6=20次50ms定时的TIMERLOOP后,R6=0不再跳转。而后将R7=60减一,并跳转INCREASE令用于计秒的寄存器R0加一,意为一秒到了。再调用显示子程序,显示新的计秒数,最后重新为R6赋20并跳转50ms定时的TIMERLOOP,开始下一秒的计时。

当DJNZ指令将R7减至0,不再跳转,执行60s计时到达后执行的IFFULL,清空R0的计秒,重新为R6赋20,R7赋60,取反P0.7来切换LED状态,再重新跳转50ms定时的TIMERLOOP进入下一个60s的定时

ORG 0BH
    DJNZ R6,TIMERLOOP        ;20x50ms=1s
    DJNZ R7,INCREASE        ;每秒计秒数增一

 

IFFULL:MOV R0,#0        ;计满后重新赋值
    MOV R7,#60
    MOV R6,#20
    CPL P0.7        ;切换LED显示状态
    JMP TIMERLOOP        ;不执行下面的INCREASE,直接跳转定时器

 

INCREASE:        ;进入下一秒
    INC R0
    CALL DISP
    MOV R6,#20        
    
TIMERLOOP:        ;50ms定时
    CLR TR0
    MOV TH0,#HIGH(15536)
    MOV TL0,#LOW(15536)
    SETB TR0
    
    RETI        ;中断子程序返回

注意:进入中断后的最后一个动作一定是开始定时器定时并用RETI返回懒汉程序,确保计时正确持续。 

(4)显示子程序

数模转换部分是重点,详解如下

A除10D后只有十进制的十位部分储存于A,且只存在于低位,高位为0000

这种情况是因为低4位可以存储的最大数值为15D,而十进制的A整数部分不可能大于10D,故而低位最大值为9(1001B),本程序是60s定时器,低位最大值为6(0110B)

最后将A的低位赋给P0.0-3,A的高位赋给P0.4-7,即传递BCD码给7447芯片。将个位显示在上方数码管,十位显示在下方数码管

DISP:MOV A,R0

 

;数模转换

    MOV B,#10        ;每次显示都重新给B赋值
    DIV AB        ;A除以B后将余数存于B
    SWAP A        ;交换A的高低位,A的数值为 <十进制A的十位>0H
    ADD A,B        ;<十进制A的十位> + <十进制A的个位> H
    
    MOV P1,A        ;传递BCD码给7447芯片译码后驱动数码管
    RET

 

注意:DIV只能用于AB,AB之间没有逗号,A除以B后将余数存于B,且存于B的低位,因为低位可以存储的最大值是15D=FH 

 4、完整代码

ORG 00H
    JMP START 


ORG 0BH    

    DJNZ R6,TIMERLOOP        ;20x50ms=1s
    DJNZ R7,INCREASE        ;每秒计秒数增一

 

IFFULL:MOV R0,#0        ;计满后重新赋值
    MOV R7,#60
    MOV R6,#20    

    CPL P0.7        ;切换LED显示状态
    JMP TIMERLOOP        ;不执行下面的INCREASE,直接跳转定时器

 

INCREASE:        ;进入下一秒
    INC R0
    CALL DISP
    MOV R6,#20
    
TIMERLOOP:        ;50ms定时
    CLR TR0
    MOV TH0,#HIGH(15536)
    MOV TL0,#LOW(15536)
    SETB TR0
    
    RETI        ;中断子程序返回
    
START:MOV TMOD,#11H
    MOV IE,#10000010B
    MOV P0,#0
    MOV R0,#0        
    MOV R6,#20
    MOV R7,#60
    CALL DISP
    CLR TR0
    MOV TH0,#HIGH(15536)
    MOV TL0,#LOW(15536)
    SETB TR0
    
REQUEST:SJMP $        ;懒汉程序
    
DISP:MOV A,R0        

;---------------------DA A

    MOV B,#10        ;每次显示都重新给B赋值
    DIV AB        ;A除以B后将余数存于B
    SWAP A        ;交换A的高低位,A的数值为 <十进制A的十位>0H
    ADD A,B        ;<十进制A的十位> + <十进制A的个位> H
;-------------------
    MOV P1,A        ;A的低位赋给P0.0-3,A的高位赋给P0.4-7,即通过7447芯片将个位显示在上方数码管,十位显示在下方数码管
    RET
    
    END

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值