设置闹钟

更新时间:2023-03-19 07:32:10 阅读: 评论:0

三国杀教程-桌上游戏

设置闹钟
2023年3月19日发(作者:电脑闪屏黑屏)

可设置8个闹钟时间的智能时钟

普通的家用时钟一般只能设置一个闹钟时间,但很多人均需为工作日、周末、早晨、午休等不同时段设置

不同的闹钟时间。如果是使用普通的闹钟,只好每次休息前重新设置,很不方便,有时甚至会出现忘记更

改闹钟设置而睡过头的情况。

针对这种情况,本人利用89C51单片机设计了一款有8种闹钟设置的时钟,通过一段时间的使用,情况良好。

1、元件清单

共阴极数码管8个

4511七段译码芯片1片

ATMEL89C51单片机1片

24C08EEPROM1片

24M晶振1个

9V变压器(3VA)1个

LM317输出可调稳压IC1个

整流桥堆1个

470uF电容1个

100uF电容1个

10uF电容1个

0.1uF电容1个

33pF电容2个

蜂鸣器1个

9014(或其它NPN管)8个

ksp92(或其它PNP管)1个

二极管2个

1K欧电阻16个

470欧电阻1个

10K欧可调电阻1个

按钮开关4个

可装四节电池的电池盒1个

万能板(约12CM*17CM)1块

所有元件按以下的电路图焊接在一块万能板上。注意LM317的输出应由低调高,以免烧IC。

1、电路图

1、功能简介

该时钟以24小时制显示时间,并可显示2000年至2049年之间的任何日期及星期,日期与时间经按键

可相互切换,可输入8个闹钟时间设置,每个闹钟设置包括响铃的时间(小时与分钟)、对工作日有效还是

对周末有效的标志,以及本项设置是否启用的标志等三部分。这8个闹钟设置均保存在EEPROM中,即使

掉电也不用重新输入。当然使用者可通过按钮对任何一个设置作修改。数码管可经按钮关闭显示,避免夜

间刺眼、影响睡眠。调节LM317输出电压,可改变数码管亮度,但电压不能低于后备电池的电压,否则后

备电池供电。用四节1.5V电池串联作后备电源,保证市电停电时时钟继续走时。时钟的精度取决于晶振频

率的精度。

2、程序清单

本程序用C语言编写,经KeilC51编译成二进制码后写入89C51内的EPROM内即可。

#include"atmelat89x鸡翅怎么做 51.h"

#include"intrins.h"

unsignedcharhour,min,c,year,month,day,weekday;//当前时间、日期、星期

unsignedintcount_down;//1秒钟计时用

bitled_on;//数码管是否点亮的标志

unsignedchardisplay[8];//8位数码管要显示的数据

unsignedcharattr;//八个数码管的闪烁控制字节,当为0时,对应数码管闪

bitflash;小学生写通知 //LED闪烁开关,与attr共同决定数码管是否闪烁

unsignedcharshow_status;//LED显示状态标志

//0:设置闹钟数据

//1:显示当前日期及星期

//2:显示当前时间

//3:设置当前日期

//4:设置当前时间

bitkm;//按键已去抖动标志

bitkp;//按键已处理标志

bitsound;//蜂鸣器响标志

bitalarm_stop;//蜂鸣器响后用户手工按停标志

struct{unsignedcharh;//小时

unsignedcharm;//分钟

}alarm[8];//8个闹钟项

unsignedcharalarm_en;//闹钟项启用标志

unsignedcharalarm_wk;//闹钟项周末启用标志

unsignedcharcur_alarm_t;//当前设置的闹钟项

unsignedcharcur_alarm_active;//当前到点的闹钟项

bitnew_alarm_info;//闹钟项内容已修改标志

sbitsound_output=P1^5;//蜂鸣器驱动端口,输出0时蜂鸣器响

sbitSDA_PIN=P1^6;//EEPROM数据线端口

sbitSCL_PIN=P1^7;//EEPROM时钟线端口

voidI2cDelay()//EEPROM操作时需要的延时函数

{_nop_();_nop_();_nop_();

_nop_();_nop_();_nop_();

}

voidDelayX1ms(unsignedcharcount)//延迟函数,参数为毫秒数

{unsignedchari,j;

for(i=0;i

for(j=0;j<240;j++);

}

voidStart()//I2C启动,24C08使用I2C方式

{SDA_PIN=1;I2cDelay();

SCL_PIN=1;I2cDelay();

SDA_PIN=0;I2cDelay();

SCL_PIN=0;

}

voidStop()//I2C停止

{I2cDelay();SDA_PIN=0;

I2cDelay();SCL_PIN=1;

I2cDelay();SDA_PIN=1;

I2cDelay();

}

bitSendByte(unsignedcharvalue)//发送1字节数据给EEPROM

{unsignedchari;

bitno_ack=0;

for(i=0;i<8;i++)//发送8位数据

{I2cDelay();

if(value&0x80)SDA_PIN=1;

elSDA_PIN=0;

value=value<<1;

I2cDelay();SCL_PIN=1;

I2cDelay();

I2cDelay();SCL_PIN=0;

}

I2cDelay();SDA_PIN=1;//确认脉冲周期,等待EEPROM的确认

I2cDelay();SCL_PIN=1;

I2cDelay();

if(SDA_PIN==1)no_ack=1;

I2cDelay();SCL_PIN=0;

returnno_ack;

}

voidmywrite(unsignedcharaddress,unsignedcharvalue)//向EEPROM写1字节

{Start();SendByte(0xa0);SendByte(address);

SendByte(value);Stop();DelayX1ms(10);

}

unsignedcharReadByte()//从EEPROM接收1字节

{unsignedchari,bval;

bval=0;

for(i=0;i<8;i++)//接收8位数据

{I2cDelay();

SDA_PIN=1;//从P1输入数据时,先往P1输入“1”

I2cDelay();SCL_PIN=1;

I2cDelay();bval=bval<<1;if(SDA_PIN)bval=bval|0x01;

I2cDelay();SCL_PIN=0;

}

I2cDelay();SDA_PIN=1;//确认脉冲周期,不送出确认

I2cDelay();SCL_PIN=1;

I2cDelay();

I2cDelay();

return(bval);

}

unsignedcharmyread(unsignedcharaddress)//从EEPROM读入1字节数据

{unsignedchartmp;

Start();SendByte(0xa0);SendByte(address);

Start();SendByte(0xa1);tmp=ReadByte();

Stop();DelayX1ms(2);

return(tmp);

}

voidTimer0ISR(void)interrupt1using3//定时器0中断程序,用于走时,1/8000秒一次

{unsignedchartmp,tmp_days;

count_down--;

if(count_down==1||count_down==2001||count_down==4001||count_down==6001)

{flash=~flash;//数码管闪烁的开关量

if(sound&&flash)sound_output=0;//驱动蜂鸣器

elsound_output=1;//关闭蜂鸣器

return;

}

/***计算当前日期为星期几***/

if(count_down==3000)

{if(year==0)weekday=5;//2000年1月1日为星期六

el{tmp=(year-1)/4+1;tmp=(year-tmp)+tmp*2;

weekday=(tmp+5)%7;//计算出当前年的1月1日为星期几

}

tmp_days=0;

for(tmp=1;tmp

if(tmp==1||tmp==3||tmp==5||tmp==7||tmp==8||tmp==10)

tmp_days=tmp_days+31;

elif(tmp==4||tmp==6||tmp==9||tmp==11)

tmp_days=tmp_days+30;

elif(tmp==2)

{if(year%4==0)tmp_days=tmp_days+29;

eltmp_days=tmp_days+28;

}

tmp_days=tmp_days+day-1;weekday=(weekday+tmp_days%7)%7+1;

return;

}

/***查询是否有闹钟时间项符合触发条件***/

if(count_down==5000)

{if((alarm_stop||sound)&&alarm[cur_alarthen是什么意思 m_active].m!=min)//触发后1分钟

{alarm_stop=0;sound=0;}//自动关蜂鸣器

if(sound==0&&alarm_stop==0)//没有已触发的闹钟项

for(tmp=0;tmp<8;tmp++)//则查询8个闹钟项内是否有符合条件的

{if(((alarm_en>>tmp)&1)==0)continue;//该闹钟项不启用

if(((alarm_wk>>tmp)&1)==1)//该闹钟项周末有效

{if(weekday!=6&&weekday!=7)continue;}//当前不是星期六或星期天

el

{if(weekday==6||weekday==7)continue;}

if(alarm[tmp].h==hour&&alarm[tmp].m==min)//比较当前时间与该

{sound=1;cur_alarm_active=tmp;break;}//闹钟项的时间

}

return;

}

if(count_down==0)//过了一秒钟

{count_down=8000;

c++;

if(c==60)

{c=0;

min++;

if(min==60)

{min=0;

hour++;

if(hour==24)

{hour=0;day++;

switch(day)

{ca29:if(month==2&&year%4){day=1;month=3;}

break;

ca30:if(month==2&&year%4==0){day=1;month=3;}

break;

ca31:if(month==4||month==6||month==9||month==11)

{day=1;month++;}

break;

ca32:day=1;month++;

if(month==13){month=1;year++;}

}

}

}

}

}

}

voidTimer1ISR(void)interrupt3using2//定时器2中断,用于按键扫描

{unsignedcharkeytmp;

chartmp;

TH1=0x15;TL1=0xa0;//每30ms中断一次

/***当前显示的内容***/

if(show_status==0)//当前正在设置闹钟项

{display[0]=cur_alarm_t;display[1]=0xf;

display[2]=alarm[cur_alarm_t].h/10;display[3]=alarm[cur_alarm_t].h%10;

display[4]=alarm[cur_alarm_t].m/10;display[5]=alarm[cur_alarm_t].m%10;

display[6]=(alarm_wk>写真图片大全 >cur_alarm_t)&1;display[7]=(alarm_en>>cur_alarm_t)&1;

}

if(show_status==1||show_status==3)//当前显示或设置日期

{display[0]=year/10;display[1]=year%10;display[2]=month/10;

display[3]=month%10;display[4]=day/10;display[5]=day%10;

display[6]=0xf;display[7]=weekday;

}

if(show_status=全民k歌歌房 =2||show_status==4)//当前显示或设置时间

{display[0]=hour/10;display[1]=hour%10;display[2]=min/10;

display[3]=min%10;display[4]=c/10;display[5]=c%10;

display[6]=0xf;display[7]=0xf;//最后两后无显示

}

/***按键扫描及处理***/

keytmp=~(P1)&0x0f;

if(keytmp==0){km=0;kp=0;}

el

{if(km==0)km=1;

el

{if(kp==0)

{kp=1;

if(keytmp==1)//第一个按钮

{if(sound){alarm_stop=1;sound=0;}//如果闹钟正响,按此键停止

elif((show_status==1||show_status==2)&&led_on)//正显示日期或时间

{show_status=0;cur_alarm_t=0;attr=0x3f;}//进入闹钟设置

elif(show_status==0)//如正在设置闹钟时间项

{show_status=2;new_alarm_info=1;attr=0xff;}//返回当前时间显示

return;

}

if(keytmp==2&&led_on)//第二个按钮,仅当数码管打开时有效

{switch(attr)

{ca0xff:if(show_status==1)show_status=2;//在显示时间与日期间切换

elif(show_status==2)show_status=1;

break;

ca0x3f:if(show_status==0)cur_alarm_t=(cur_alarm_t+1)%8;

elif(show_status==3)

year=(year+1)%50;//当前日期的“年”加1

elif(show_status==4)

hour=(hour+1)%24;//当前时间的“时”加1

break;

ca0xcf:if(show_status==0)//闹钟设置的“时”加1

alarm[cur_alarm_t].h=(alarm[cur_alarm_t].h+1)%24;

elif(show_status==3)

{month++;//当前日期的“月”加1

if(month==13)month=1;}

elif(show_status==4)

min=(min+1)%60;//当前时间的“分”什么洗发水最好 加1

break;

ca0xf3:if(show_status==0)

alarm[cur_alarm_t].m=(alarm[cur_alarm_t].m+1)%60;

elif(show_status==3)

{day++;//当前日期的“日”加1

if(day==32)day=1;}

elif(show_status==4)

{count_down=8000;

c=(c+1)%60;}//当前时间的“秒”加1

break;

ca0xfd:if(show_status==0)

alarm_wk^=0x1<

break;

ca0xfe:if(show_status==0)

alarm_en^=0x1<

}//endofswitch(attr)

return;

}//endofif(keytmp==1)

if(keytmp==4)//第三个按钮

{switch(attr)

{ca0xff:if(show_status==1||show_status==2)

led_on=~led_on;//打开或关闭数码管显示

break;

ca0x3f:if(show_status==0)//如果正在设置闹钟

{if(cur_alarm_t==0)cur_alarm_t=7;

elcur_alarm_t--;}

elif(show_status==3)//当前日期的“年”减1

{if(year==0)year=49;elyear--;}

elif(show_status==4)//当前时间的“时”减1

{tmp=hour-1;if(tmp<0)hour=23;el

hour=tmp;}

break;

ca0xcf:if(show_status==0)//闹钟设置的“时”减1

{tmp=alarm[cur_alarm_t].h-1;

if(tmp<0)alarm[cur_alarm_t].h=23;

elalarm[cur_alarm_t].h=tmp;

}

elif(show_status==3)

{month--;//当前日期的“月”减1

if(month==0)month=12;}

elif(show_status==4)

{tmp=min-1;//当前时间的“分”减1

if(tmp<0)min=59;elmin=tmp;}

break;

ca0xf3:if(show_status==0)//闹钟设置的“分钟”减1

{tmp=alarm[cur_alarm_t].m-1;

if(tmp<0)alarm[cur_alarm_t].m=59;

elalarm[cur_alarm_t].m=tmp;

}

elif(show_status==3)

{day--;//当前日期的“日”减1

if(day==0)day=31;}

elif(show_status==4)

{tmp=c-1;//当前时间的“秒”减1

count_down=8000;

if(tmp<0)c=59;elc=tmp;}

break;

ca0xfd:if(show_status==0)//切换周末标志

alarm_wk^=0x1<

break;

ca0xfe:if(show_status==0)//切换启用标志

alarm_en^=0x1<

}//endofswitch(attr)

return;

}//endofif(keytmp==2)

if(keytmp==8&led_on)//第四个按钮,仅当数码管打开时有效

{switch(attr)

{ca0xff:if(show_status==1)//如果当前显示日期

show_status=3;//切换到调准日期状态

elif(show_status==2)//如果当前显示时间

show_status=4;//切换到调准时间状态

attr=0x3f;break;//第一、二个数码管闪烁

ca0x3f:attr=0xcf;break;//第三、四个数码管闪烁

ca0xcf:attr=0xf3;break;//第五、六个数码管闪烁

ca0xf3:if(show_status==0)attr=0xfd;//第七个数码管闪烁

elif(show_status==3)

{show_status=1;attr=0xff;}//恢复正常显示日期

elif(show_status==4)

{show_status=2;attr=0xff;}//恢复正常显示时间

break;

ca0xfd:if(show_status==0)attr=0xfe;//第八个数码管闪烁

break;

ca0xfe:if(show_status==0)attr=0x3f;//第一、二个数码管闪烁

}

}//endofif(keytmp==4)

}//endofif(kp==0)

}//endofif(km==0)

}//endofif(keytmp!=0)

}

main()

{unsignedchari;

hour=23;min=58;c=30;year=2;month=4;day=25;

count_down=8000;

flash=0;attr=0xff;led_on=1;

km=0;kp=0;show_status=2;//加电后显示当前时间

new_alarm_info=0;sound=0;alarm_stop=0;

for(i=0;i<8;i++)//从EEPROM中读入8个闹钟设置

{alarm[i].h=myread(i*2);alarm[i].m=myread(i*2+1);}

alarm_en=myread(i*2);alarm_wk=myread(i*2+1);

IE=0;IP=0;//disableallinterruptandlowerpriority

TMOD=0x12;//timer0isttomode2,auto_reloading,timer1,mode1

TH0=6;TL0=6;//timer0parametersfor0.125ms

TH1=0x15;TL1=0xa0;//timer1parametersfor30ms

TR0=1;TR1=1;//timer0interruptmostimportant

ET0=1;ET1=1;EA=1;//enableinterruptfunction

while(1)

{if(led_on)

for(i=0;i<8;i++)

{P2=0;

if(flash||attr&(0x80>>i))

{P0=display[i];P2=0x80>>i;DelayX1ms(1);}

}

elP2=0;

if(new_alarm_info)

{P2=0;//暂时关闭数码管

new_alarm_info=0;//写入EEPROM

for(i=0;i<8;i++){mywrite(i*2,alarm[i].h);mywrite(i*2+1,alarm[i].m);}

mywrite(i*2,alarm_en);mywrite(i*2+1,alarm_wk);

}

}

}

本文发布于:2023-03-19 07:32:07,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/1679182330308142.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:设置闹钟.doc

本文 PDF 下载地址:设置闹钟.pdf

上一篇:怎么打开u盘
下一篇:返回列表
标签:设置闹钟
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图