📄 djskz.asm
字号:
;**************************************************
;djskz.asm
;可设定倒计时控制
;数码管在按键的控制下可以显示所有设置的小时时间秒数(0~99)
;当外部中断信号 来临 的时候以该数字位初值进行倒计时计数,并控制继电器
;great by 2008-3-15 lus2008
;**************************************************
;定义变量
DisplayBuffer equ 30h ;显示数据缓冲器为30h-31h
Modedis equ 33h ;显示数据存放
OneSecondCounter equ 34h ;1s中断次数
Danqians equ 35h ;存储上一次的数据
Daojs equ 20h.1 ;中断来临标志位
Addkey bit P3.4 ;设置加按键
Deckey bit P3.3 ;设置减按键
RelayOut equ P3.0 ;定义输出引脚,扬声器控制
RelayOut1 equ P3.5 ;定义输出引脚,继电器1控制
;程序开始
org 00h
ajmp Main
org 03h
ajmp Intsig
org 0bh
ajmp Inttimer
org 20h
Main:
;中断初始化
mov sp,#50h
mov ie,#10000011b ;启动中断总开关ea和外部中断0开关ex0,et0
setb it0 ;采用脉冲负降沿启动中断
;定时器初始化
mov tmod,#00000001b ; ;使用定时器0,方式1
mov th0,#0E3h ; 8ms
mov tl0,#33h
clr Daojs ;将标志位清0
mov OneSecondCounter,#125 ;1s钟中断次数
;*****************************************************************
;主程序开始
;*****************************************************************
;按键选择,数码管显示的数据的设置
mov Modedis,#02
Loop2: mov a,Modedis
lcall Disshu ;将数据放入缓冲区
Loop5: jb Addkey,Next2
lcall Delayd
jb Addkey,Next2
mov a,Modedis
add a,#1
cjne a,#99,Loop
mov a,#0
Loop: jnb Addkey,$
mov Modedis,a
lcall Disshu ;将数据放入缓冲区
Next2: jb Deckey,Next
lcall Delayd
jb Deckey,Next
mov a,Modedis
dec a
cjne a,#00h,Loop1
mov a,#98
Loop1: jnb Deckey,$
mov Modedis,a
lcall Disshu ;将数据放入缓冲区
Next: ajmp Loop2
;
;*****************************************************************
;数据存储,扫描显示
;*****************************************************************
;将数据存储到缓存里
Disshu: mov r1,#DisplayBuffer
mov a,Modedis ;将存储区里的数据分位放入缓冲区
mov b,#10
div ab
mov @r1,b
inc r1
mov @r1,a
call Candis ;显示缓冲区里的数据
ret
;将缓冲区里的数据显示到数码管上
Candis: mov r1,#DisplayBuffer
mov r4,#11011111b ;选择右边第一个数码管,其次选择第二个
Again: mov a,r4
mov p2,a
mov a,@r1
mov dptr,#tab
movc a,@a+dptr
mov p0,a ;显示第一个数据
inc r1
mov a,r4
jnb acc.3,Nextd
rr a
mov r4,a
lcall Delays ;2ms间隔显示时间
ajmp Again
Nextd: mov p2,#0ffh
ret
tab: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,7FH,0B7H,0FFH
;共阳段码表 "0""1""2" "3""4""5""6""7" "8""9"".""=""不亮"
;
;*****************************************************************
;中断服务子程序
;*****************************************************************
;中断服务子程序
Intsig: push acc
push psw
setb tr0
; mov a,
mov Danqians,Modedis
pop psw
pop acc
reti
;定时器中断服务程序
Inttimer:
mov th0,#0E3h ;重新加载定时参数
mov tl0,#33h
push acc
push psw ; 保护累加器及程序状态字的内容
djnz OneSecondCounter,NotoneSecond ;中断了125次了吗?即够1秒了吗?
mov OneSecondCounter,#125 ;如够1秒则重新设置"OneSecondCounter"计数器
lcall Jiano ;调用减1秒的子程序
lcall Disshu ;将数据放入缓冲区
NotoneSecond:
lcall Candis ;调用扫描显示子程序
pop psw
pop acc ;恢复累加器及程序状态字的内容
reti ;中断返回
;
;*****************************************************************
;其他子程序
;*****************************************************************
;将当前显示的值减1子程序
Jiano: mov a,Modedis ;取得当前值
dec a
mov Modedis,a
cjne a,#00h,Next5
lcall Alrmk ;倒计时间到
Next5: ret
;
;倒计时间到服务程序
Alrmk: clr tr0 ;关闭定时器
mov Modedis,Danqians ;该地方,不能用a寄存器来转接?????
lcall Disshu ;将数据放入缓冲区
clr RelayOut ;启动继电器1
clr RelayOut1 ;启动扬声器
mov r2,#200
lop: mov Modedis,Danqians ;使用动态显示程序达到延时间效果
lcall Disshu ;将数据放入缓冲区
djnz r2,lop
setb RelayOut ;启动继电器1
setb RelayOut1 ;启动扬声器
clr tr0
ret
;
;防止抖动延时 20ms
Delayd: mov r7,#8
D1: mov r6,#122
djnz r6,$
djnz r7,D1
ret
;数码管显示间隔延时 16ms
Delays: mov r7,#2
D2: mov r6,#245
djnz r6,$
djnz r7,D2
ret
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -