您现在所在的是:

单片机论坛

回帖:0个,阅读:2148 [上一页] [1] [下一页]
967
zidh
文章数:22
年度积分:50
历史总积分:967
注册时间:2006/8/27
发站内信
发表于:2007/6/29 18:21:00
#0楼
带有时间设置和秒显示的数字闹钟源代码及原理图
完整的数字电子闹钟源代码(后附:原理图),详细中文注释,课程设计,毕业设计参考首选

;*********************************************************
;           带有时间设置和秒显示的数字闹钟(后附原理图)
;   晶振            12MHZ                                
;  Create by : 逸飞    mcu-yf@163.com     QQ:504577663

; 版权所有 :中国自动化资讯网 www.zidh.com   转载,请注明出处
; 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分了吗?
         mov Minute,#0;                    够了则将分值清0
         ;
         mov a,Hour
         add a,#1
         mov Hour,a;                       小时加1
         cjne a,#18H,NotOverFlow;          够24小时吗?
         mov Hour,#0;                      够了则将小时值清0
NotOverFlow:
         jnb AlarmOnOff,NotAlarm;          闹钟开启了吗?如没有开启则无需理会是否到闹时时间
         mov a,Second
         jnz NotAlarm;                     秒为零吗?
         mov a,Minute
         cjne a,AlarmMinute,NotAlarm;      时间分钟值和闹时设置分钟值相等吗?
         mov a,Hour
         cjne a,AlarmHour,NotAlarm;        时间小时值和闹时设置小时值相等吗?
         setb AlarmTimeOn;                 到了闹时时间则将“闹时时间到”标志设为1
NotAlarm:
         ret
         ;
;**************************************************************************
;            将时钟内容或闹时设置值转换到显示缓冲区子程序
;**************************************************************************
ConvertoBuffer:
         mov r1,#DisplayBuffer
         jb ClockMode,DispAlarmSet;        判断时钟模式,以决定是显示实时时间还是闹时时间
         mov a,Second;
         mov DispSecond,a;
         mov a,Minute;
         mov Dispminute,a;
         mov a,Hour;
         mov DispHour,a;                   显示实时时间
         ;
         ajmp Convert
DispAlarmSet:
         jb AlarmOnOff,AlarmOn
         mov DispSecond,#00h
         ajmp Next
AlarmOn:
         mov DispSecond,#11;             显示闹时时间及显示闹钟状态:显示“00”表示关闭闹钟,
Next:                                    ;“11”表示开启闹钟
         mov a,AlarmMinute;
         mov Dispminute,a;
         mov a,AlarmHour;
         mov DispHour,a;
                        ;
Convert:
         mov a,DispSecond;                取秒值
         mov b,#10
         div ab                              
         mov @r1,b;                      
         inc r1;                          缓冲寄存器的地址加1
         mov @r1,a;                       将秒值的十位值存入缓冲区
         ;                                
         inc r1
         mov a,DispMinute
         mov b,#10
         div ab                            
         mov @r1,b;                      
         inc r1;                          缓冲寄存器的地址加1
         mov @r1,a;                       将秒值的十位值存入缓冲区
         ;                                
         inc r1
         mov a,DispHour
         mov b,#10
         div ab                            
         mov @r1,b;                      
         inc r1;                          缓冲寄存器的地址加1
         mov @r1,a;                       将秒值的十位值存入缓冲区
         ;                                
         ret;                        

;**************************************************
;                   闹时设置子程序
;**************************************************
AlarmSet:
         jnb  AlarmSetKey,$
         call Delay;                     等待“AlarmSetKey”键释放
CheckArmMinuteKey:          ;
         jb MinuteKey,CheckArmHourKey;   分设置键按下了吗?没有则转去检测小时设置键
         setb AlarmOnOff
         mov a,AlarmMinute
         add a,#1;                       如果按下则将分钟加1                          十进制调整
         mov AlarmMinute,a;
         cjne a,#3ch,ArmNotOver1;        到60分钟了吗?
         mov AlarmMinute,#0;             到60分钟则将分钟清0
ArmNotOver1:                             ;以下等待按键释放及防抖动
         jnb  MinuteKey,$
CheckArmHourKey:
         jb HourKey,AlarmSetEnd;         小时设置键按下了吗?没有则返回反复检测
         setb AlarmOnOff
         mov a,AlarmHour
         add a,#1;                       如果按下则将小时加1
         mov AlarmHour,a
         cjne a,#18h,ArmNotOver2
         mov AlarmHour,#0;               到24小时则将小时清0
ArmNotOver2:                             ;以下等待按键释放及防抖动
         jnb  HourKey,$
AlarmSetEnd:
         jb AlarmSetKey,AlarmSet;        设置完毕了吗?
         jnb AlarmSetKey,$;
         clr ClockMode;                  从设置模式转为走时模式
         ret

;**************************************************
;             闹时服务子程序
;**************************************************
AlarmProcess:
         clr RelayOut;
         jb AlarmSetKey,AlarmReturn;   停止闹时键(即闹时设置键)按下了吗?
  clr AlarmOnOff
         jnb AlarmSetKey,$;
         setb  RelayOut;                如停止闹时键按下则停止闹时
         clr AlarmTimeOn;
AlarmReturn:
         ret
;**************************************************
;          延时子程序
;**************************************************
Delay:
         mov r6,#2
Del:
         mov r7,#249
         djnz r7,$
         djnz r6,Del
         ret
         end

;完整的数字电子闹钟源代码,详细中文注释,课程设计,毕业设计参考首选。

原理图下载页面:http://www.zidh.com/Soft/xzsoft/200706/119.html
自动化工程师的网上家园!
   E-mail: zidh.com@163.com
   E-mail: mcu-yf@163.com
兴趣是最好的老师,努力就有方向!
我自信我成功,还等什么大家一起来学习!

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2024 Gkong.com, All Rights Reserved

78.0005