带有时间设置和秒显示的数字闹钟
——
; 带有时间设置和秒显示的数字闹钟
; Date : 2006.3.13 12MHZ晶振
; Create by :尘封往事 逸飞
; P3.2设置键 P3.3小时调整键 P3.5分钟调整键 P1.7定时输出指示
;**************************************************************
;*********************************************************
; 变量地址分配
;*********************************************************
SwDelay equ 2; 设置按键时去抖动时间
DisplayBuffer equ 30h; 设置显示缓冲区的地址为30h-35h共6个字节
BeepVal equ 36h; 蜂鸣时间长短存储器地址
OneSecondCounter equ 39h; 设置1秒计数器的地址,1秒计数器是用来计数1秒内计时器的中断次数
Hour equ 3ah; 设置小时计数器的地址
Minute equ 3bh; 设置分钟计数器的地址
Second equ 3ch; 设置秒计数器的地址
P1Val equ 3dh; 设置数码管位驱动值的地址
ClockMode equ 20h.0; 模式(正常走时/闹时)设置寄存器地址,值为0时正常走时,为1时闹时设定
AlarmOnOff equ 20h.1; 闹钟开启/关闭标志,为0关闭,为1开启
AlarmTimeOn equ 20h.2; 此位为1时表示闹时时间到
DispHour equ 21h; 设置小时显示寄存器的地址
DispMinute equ 22h; 设置分钟显示寄存器的地址
DispSecond equ 23h; 设置秒显示寄存器的地址
AlarmHour equ 2eh; 设置闹时小时计数器的地址
AlarmMinute equ 2fh; 设置闹时分钟计数器的地址
AlarmSetKey bit P3.2; 闹钟设置键
MinuteKey bit P3.5; 定义分设置键
HourKey bit P3.3; 定义小时设置键
RelayOut equ P1.7; 定义输出引脚
;**********************************************************************
; 程序开始
;**********************************************************************
org 00h
ajmp Reset; 程序开始
org 0bh ; Timer0中断向量地址
ajmp TimeInt; 跳到中断处理程序
org 0020h
Reset: ; 以下为初始化程序,为各个变量赋初值
mov sp,#70h;
setb RelayOut
mov OneSecondCounter,#125
;
mov Hour,#12;
mov Minute,#00;
mov Second,#00; 设置上电时时钟显示的初值
;
mov AlarmHour,#06;
mov AlarmMinute,#00; 设置上电时闹时时间的初值
;
clr AlarmOnOff; 上点复位后闹时功能处于关闭状态
clr ClockMode; 正常走时模式
clr AlarmTimeOn;
setb RelayOut; 清闹时输出
;************************************
; Use Timer 0 Mode 1
; 400us interrupt
;************************************
mov tmod,#00000001b;
mov th0,#0E3h;
mov tl0,#39h;
mov ie, #82h; 开全局中断
setb tr0; 开定时中断
;*****************************************
; 以下为主程序
;*****************************************
MainLoop:
jb AlarmSetKey,CheckMinuteKey; 闹时设置键按下了吗?没有则转去检测秒设置键
;
call Delay;
jb AlarmSetKey,CheckMinuteKey; 按下的时间超过500ms吗?
setb ClockMode; 置为闹时设置模式
call AlarmSet;
CheckMinuteKey:
jb MinuteKey,CheckHourKey; 分设置键按下了吗?没有则转去检测小时设置键
; 如按下调用蜂鸣器发音程序
mov a,Minute
add a,#1; 如果按下则将分钟加一 十进制调整
mov Minute,a;
cjne a,#3ch,NotOver1; 到60分钟了吗?
mov Minute,#0; 到60分钟则将分钟清0
NotOver1: ;以下等待按键释放及防抖动
jnb MinuteKey,$
CheckHourKey:
jb HourKey,CheckAlarm; 小时设置键按下了吗?没有则转去闹时状态检测
; 如按下调用蜂鸣器发音程序
mov a,Hour
add a,#1; 如果按下则将小时加1
mov Hour,a
cjne a,#18h,NotOver2
mov Hour,#0; 到24小时则将小时清0
NotOver2: ;以下等待按键释放及防抖动
jnb HourKey,$
CheckAlarm: ;
jnb AlarmTimeOn,ToReturn
call AlarmProcess
ToReturn:
ajmp MainLoop
;**********************************************
; 定时器Timer0中断服务程序(此程序每8ms执行一次)
;********************************************** {{分页}}
TimeInt:
mov th0,#0E3h; 重新加载定时参数
mov tl0,#39h;
push acc
push psw; 保护累加器及程序状态字的内容
setb rs0; 选择工作寄存器组1,
clr rs1; 这样可保护原工作寄存器组(0组)的内容
djnz OneSecondCounter,NotoneSecond; 中断了125次了吗?即够1秒了吗?
mov OneSecondCounter,#125; 如够1秒则重新设置"OneSecondCounter"计数器
call Clock ; 调用将时钟内容加1秒的子程序
call ConvertoBuffer ; 调用将时钟内容转换到显示缓冲区子程序
NotoneSecond:
call ScanDisplay ; 调用扫描显示子程序
pop psw
pop acc ; 恢复累加器及程序状态字的内容
reti ; 中断返回
;*********************************************
; 扫描显示子程序
;*********************************************
ScanDisplay:
MOV R1,#DisplayBuffer ;指向显示数据首址
MOV R4,#11111011b ;扫描控制字初值
PLAY: MOV A,R4 ;扫描字放入A
MOV P2,A ;从P2口输出
MOV A,@R1 ;取显示数据到A
MOV DPTR,#TAB ;取段码表地址
MOVC A,@A+DPTR ;查显示数据对应段码
MOV P0,A ;段码放入P1口
LCALL Delay
INC R1 ;指向下一地址
MOV A,R4 ;扫描控制字放入A
JNB ACC.7,ENDOUT ;扫到第六位时结束
RL A ;A中数据循环左移
MOV R4,A ;放回R5内
AJMP PLAY ;跳回PLAY循环
ENDOUT: SETB P2.7 ;一次显示结束,P2口复位
MOV P0,#0FFH ;P0口复位
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"".""=""不亮"
;****************************************************
; 时钟内容加1秒的子程序
;****************************************************
Clock:
mov a,Second; 将原秒值送入a
add a,#1; 加1秒
mov Second,a
cjne a,#3cH,NotOverFlow; 够60秒了吗?
mov Second,#0; 够了则将秒值清0
;
mov a,Minute
add a,#1
mov Minute,a; 分钟加1
cjne a,#3cH,NotOverFlow; 够60分了吗?
&n 尘埃粒子计数器相关文章:尘埃粒子计数器原理 蜂鸣器相关文章:蜂鸣器原理
评论