可设置八个闹钟的智能时钟原理图+程序Word格式文档下载.docx

上传人:b****5 文档编号:19487071 上传时间:2023-01-06 格式:DOCX 页数:14 大小:35.39KB
下载 相关 举报
可设置八个闹钟的智能时钟原理图+程序Word格式文档下载.docx_第1页
第1页 / 共14页
可设置八个闹钟的智能时钟原理图+程序Word格式文档下载.docx_第2页
第2页 / 共14页
可设置八个闹钟的智能时钟原理图+程序Word格式文档下载.docx_第3页
第3页 / 共14页
可设置八个闹钟的智能时钟原理图+程序Word格式文档下载.docx_第4页
第4页 / 共14页
可设置八个闹钟的智能时钟原理图+程序Word格式文档下载.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

可设置八个闹钟的智能时钟原理图+程序Word格式文档下载.docx

《可设置八个闹钟的智能时钟原理图+程序Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《可设置八个闹钟的智能时钟原理图+程序Word格式文档下载.docx(14页珍藏版)》请在冰豆网上搜索。

可设置八个闹钟的智能时钟原理图+程序Word格式文档下载.docx

//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_set;

//当前设置的闹钟项

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_();

}

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

{unsignedchari,j;

for(i=0;

i<

count;

i++)

for(j=0;

j<

240;

j++);

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

{SDA_PIN=1;

I2cDelay();

SCL_PIN=1;

SDA_PIN=0;

SCL_PIN=0;

voidStop()//I2C停止

{I2cDelay();

SDA_PIN=1;

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

{unsignedchari;

bitno_ack=0;

8;

i++)//发送8位数据

{I2cDelay();

if(value&

0x80)SDA_PIN=1;

elseSDA_PIN=0;

value=value<

<

1;

}

//确认脉冲周期,等待EEPROM的确认

if(SDA_PIN==1)no_ack=1;

returnno_ack;

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

{Start();

SendByte(0xa0);

SendByte(address);

SendByte(value);

Stop();

DelayX1ms(10);

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

{unsignedchari,bval;

bval=0;

i++)//接收8位数据

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

bval=bval<

if(SDA_PIN)bval=bval|0x01;

//确认脉冲周期,不送出确认

return(bval);

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

{unsignedchartmp;

Start();

SendByte(0xa1);

tmp=ReadByte();

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;

//驱动蜂鸣器

elsesound_output=1;

//关闭蜂鸣器

return;

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

if(count_down==3000)

{if(year==0)weekday=5;

//2000年1月1日为星期六

else{tmp=(year-1)/4+1;

tmp=(year-tmp)+tmp*2;

weekday=(tmp+5)%7;

//计算出当前年的1月1日为星期几

tmp_days=0;

for(tmp=1;

tmp<

month;

tmp++)

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

tmp_days=tmp_days+31;

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

tmp_days=tmp_days+30;

elseif(tmp==2)

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

elsetmp_days=tmp_days+28;

tmp_days=tmp_days+day-1;

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

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

if(count_down==5000)

{if((alarm_stop||sound)&

alarm[cur_alarm_active].m!

=min)//触发后1分钟

{alarm_stop=0;

sound=0;

}//自动关蜂鸣器

if(sound==0&

alarm_stop==0)//没有已触发的闹钟项

for(tmp=0;

tmp++)//则查询8个闹钟项内是否有符合条件的

{if(((alarm_en>

>

tmp)&

1)==0)continue;

//该闹钟项不启用

if(((alarm_wk>

1)==1)//该闹钟项周末有效

{if(weekday!

=6&

weekday!

=7)continue;

}//当前不是星期六或星期天

else

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

if(alarm[tmp].h==hour&

alarm[tmp].m==min)//比较当前时间与该

{sound=1;

cur_alarm_active=tmp;

break;

}//闹钟项的时间

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

{count_down=8000;

sec++;

if(sec==60)

{sec=0;

min++;

if(min==60)

{min=0;

hour++;

if(hour==24)

{hour=0;

day++;

switch(day)

{case29:

if(month==2&

year%4){day=1;

month=3;

break;

case30:

year%4==0){day=1;

case31:

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

{day=1;

month++;

break;

case32:

day=1;

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_set;

display[1]=0xf;

display[2]=alarm[cur_alarm_set].h/10;

display[3]=alarm[cur_alarm_set].h%10;

display[4]=alarm[cur_alarm_set].m/10;

display[5]=alarm[cur_alarm_set].m%10;

display[6]=(alarm_wk>

cur_alarm_set)&

display[7]=(alarm_en>

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==2||show_status==4)//当前显示或设置时间

{display[0]=hour/10;

display[1]=hour%10;

display[2]=min/10;

display[3]=min%10;

display[4]=sec/10;

display[5]=sec%10;

display[7]=0xf;

//最后两后无显示

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

keytmp=~(P1)&

0x0f;

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

kp=0;

}

else

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

else

{if(kp==0)

{kp=1;

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

{if(sound){alarm_stop=1;

}//如果闹钟正响,按此键停止

elseif((show_status==1||show_status==2)&

led_on)//正显示日期或时间

{show_status=0;

cur_alarm_set=0;

attr=0x3f;

}//进入闹钟设置

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

{show_status=2;

new_alarm_info=1;

attr=0xff;

}//返回当前时间显示

return;

}

if(keytmp==2&

led_on)//第二个按钮,仅当数码管打开时有效

{switch(attr)

{case0xff:

if(show_status==1)show_status=2;

//在显示时间与日期间切换

elseif(show_status==2)show_status=1;

case0x3f:

if(show_status==0)cur_alarm_set=(cur_alarm_set+1)%8;

elseif(show_status==3)

year=(year+1)%50;

//当前日期的“年”加1

elseif(show_status==4)

hour=(hour+1)%24;

//当前时间的“时”加1

break;

case0xcf:

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

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

{month++;

//当前日期的“月”加1

if(month==13)month=1;

min=(min+1)%60;

//当前时间的“分”加1

break;

case0xf3:

if(show_status==0)

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

{day++;

//当前日期的“日”加1

if(day==32)day=1;

{count_down=8000;

sec=(sec+1)%60;

}//当前时间的“秒”加1

case0xfd:

if(show_status==0)

alarm_wk^=0x1<

cur_alarm_set;

//周末标志位切换

break;

case0xfe:

alarm_en^=0x1<

//启用标志位切换

}//endofswitch(attr)

}//endofif(keytmp==1)

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

if(show_status==1||show_status==2)

led_on=~led_on;

//打开或关闭数码管显示

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

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

elsecur_alarm_set--;

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

{if(year==0)year=49;

elseyear--;

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

{tmp=hour-1;

if(tmp<

0)hour=23;

elsehour=tmp;

case0xcf:

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

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

if(tmp<

0)alarm[cur_alarm_set].h=23;

elsealarm[cur_alarm_set].h=tmp;

}

{month--;

//当前日期的“月”减1

if(month==0)month=12;

elseif(show_status==4)

{tmp=min-1;

//当前时间的“分”减1

0)min=59;

elsemin=tmp;

break;

case0xf3:

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

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

0)alarm[cur_alarm_set].m=59;

elsealarm[cur_alarm_set].m=tmp;

{day--;

//当前日期的“日”减1

if(day==0)day=31;

{tmp=sec-1;

//当前时间的“秒”减1

count_down=8000;

0)sec=59;

elsesec=tmp;

case0xfd:

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

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

}//endofif(keytmp==2)

if(keytmp==8&

led_on)//第四个按钮,仅当数码管打开时有效

{case0xff:

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

show_status=3;

//切换到调准日期状态

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

show_status=4;

//切换到调准时间状态

attr=0x3f;

//第一、二个数码管闪烁

attr=0xcf;

//第三、四个数码管闪烁

attr=0xf3;

//第五、六个数码管闪烁

if(show_status==0)attr=0xfd;

//第七个数码管

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1