可调多功能温度时钟.docx
《可调多功能温度时钟.docx》由会员分享,可在线阅读,更多相关《可调多功能温度时钟.docx(23页珍藏版)》请在冰豆网上搜索。
可调多功能温度时钟
//多功能时钟(时间+温度+整点报时+可调节)已经调试成功,可以直接移植。
#include
#include"intrins.h"
#defineucharunsignedchar
#defineuintunsignedint
ucharmin,sec=0,hour,counts,flm,hsec,time[12];
uchartimes=0,flag;
uchartian,yue,year=2019;
ucharnhour,nmin,nsec;
unsignedcharT1RH,T1RL;
unsignedintj=0;
unsignedchardispcode[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xa7,0xFF};//共阳数码管段码
unsignedchardispbuf[12];
sbitdian=P3^7;
sbitK1=P2^4;
sbitK2=P2^6;
sbitK3=P2^5;
sbitK4=P2^7;
sbitDQ=P3^2;
sbitBEEP=P1^2;
sbitIRIN=P3^3;
sbitSDA=P1^7;
sbitSCL=P1^6;
bitflag_P=0,flag_M=0;
bitflag_alarm=0;
bitalarm_on=0;
//********************24C02******************//
voiddelay_us();
voidstart();
voidstop();
voidack();
voidnack();
voidwrite_24c02byte(uchardate);
ucharread_24c02byte();
voidwrite_24c02(ucharaddress,uchardate);
ucharread_24c02(ucharaddress);
voidConfigTimer1(unsignedintms);
voidbaoshi();
voidRiQi_time(void);
voidalarm();
voidClock_time(void);
voiddelay_us()//5_us延时
{
;;;
}
voidstart()//起始信号
{
//SDA=1;
SCL=1;
SDA=1;//前后位置都没有关系
delay_us();
SDA=0;
delay_us();
}
voidstop()//终止信号
{
SDA=0;
SCL=1;
delay_us();
SDA=1;
delay_us();
}
voidack()//应答信号
{
uchari;
SCL=1;
delay_us();
while((SDA==1)&&(i<250))i++;
SCL=0;
delay_us();
}
voidnack()//无应答信号
{
SCL=0;//时序图是在SCL为低电平期间,SDA变高则为非应答信号
delay_us();
SDA=1;
SCL=0;
delay_us();
}
voidwrite_24c02byte(uchardate)//带行参//写入一个字节到I2C总线
{
uchari,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
SCL=0;
delay_us();
SDA=CY;//移到CY位的1赋给SDA(准备好了数据)
delay_us();
SCL=1;//来个上升沿数据送走
delay_us();
}
SCL=0;//拉低是为下一次拉高准备
delay_us();
SDA=1;//释放数据总线
delay_us();
}
ucharread_24c02byte()//带返回值,//从I2C读一个字节
{
uchari,j,k;
SCL=0;
delay_us();
for(i=0;i<8;i++)
{
SCL=1;
delay_us();
j=SDA;
k=(k<<1)|j;//k<<1,那么最低位变为0,
SCL=0;//与J相或,是1为1,是0为0.
delay_us();//循环8次K得到8位数据,即一个字节
}
returnk;
}
voidwrite_24c02(ucharaddress,uchardate)//向24C02里面写数据
{
start();
write_24c02byte(0xa0);
ack();
write_24c02byte(address);
ack();
write_24c02byte(date);
ack();
stop();
}
ucharread_24c02(ucharaddress)//从24c02中读数据
{
uchardate;
start();
write_24c02byte(0xa0);
ack();
write_24c02byte(address);
ack();
start();
write_24c02byte(0xa1);
ack();
date=read_24c02byte();
nack();
stop();
returndate;
}
//*******************24C02********************//
voiddelay(uintt)
{
for(;t>0;t--);
}
voiddi(void)
{
uinti;
for(i=0;i<80;i++)
{
BEEP=~BEEP;
delay(100);
}
BEEP=1;
}
voidbaoshi()//整点报时函数
{
if(((hour>=8)&&(hour<=20))&&(min==00)&&(sec==00))
{
BEEP=0;
delay(100);
BEEP=1;
}
if(sec==1)
{
BEEP=1;
}
}
voidtime1(void)interrupt3using0
{
hsec++;//ms
TH1=T1RH;//加载T0重载值
TL1=T1RL;
TF1=0;
if(hsec==100)
{
hsec=0;
sec++;
if(sec==60)
{
sec=0;
flag=1;//1秒到后的标志位
min++;
if(min==60)
{
min=0;
write_24c02(2,min);
delay(10);
hour++;
if(hour==24)
{
hour=0;
write_24c02(1,hour);
delay(10);
tian++;
switch(tian)
{
case29:
if(yue==2&&year%4){tian=1;yue=3;}
break;
case30:
if(yue==2&&year%4==0){tian=1;yue=3;}
break;
case31:
if(yue==4||yue==6||yue==9||yue==11)
{tian=1;yue++;}
break;
case32:
tian=1;yue++;
if(yue==13){yue=1;year++;}
}
write_24c02(3,tian);
delay(10);
write_24c02(4,yue);
delay(10);
}
write_24c02(1,hour);
delay(10);
}
write_24c02(2,min);
delay(10);
}
}
}
voidadd_time(void)
{
switch(counts)
{
case1:
min++;min=min%60;
write_24c02(2,min);
break;//counts为1:
调分模式
case2:
hour++;hour=hour%24;
write_24c02(1,hour);
break;//counts为2:
调时模式
case3:
tian++;if(tian==31){tian=1;};
write_24c02(3,tian);
break;
case4:
yue++;if(yue==13){yue=1;};
write_24c02(4,yue);
break;
case5:
nmin++;if(nmin==60){nmin=0;};
write_24c02(5,nmin);
break;
case6:
nhour++;if(nhour==24){nhour=0;};
write_24c02(6,nhour);
break;
}
return;
}
voidsub_time(void)
{
switch(counts)
{
case1:
if(min==0){min=60;};min--;
write_24c02(2,min);
break;
case2:
if(hour==0){hour=24;};hour--;
write_24c02(1,hour);
break;
case3:
if(tian==1){tian=31;};tian--;
write_24c02(3,tian);
break;
case4:
if(yue==1){yue=13;};yue--;
write_24c02(4,yue);
break;
case5:
if(nmin==0){nmin=60;};nmin--;
write_24c02(5,nmin);
break;
case6:
if(nhour==0){nhour=24;};nhour--;
write_24c02(6,nhour);
break;
}
return;
}
voidcheck_button(void)
{
if(K1==0&&flag_P==0)//00000000&&00000000
{//模式键
delay(300);
if(K1==0)
{
flag_P=1;//标志位置1,相当于WHILE(!
K1),松手
TR1=0;//停止走时
counts++;
if(counts>=7)
{
counts=0;
sec=0;
TR1=1;//调节完后,继续走时
}
}
}
if(K3==0&&flag_P==0)//加键
{
delay(300);
if(K3==0)
{
flag_P=1;
add_time();
}
}
if(K2==0&&flag_P==0)//减键
{
delay(300);
if(K2==0)
{
flag_P=1;
sub_time();
}
}
if(K4==0&&flag_P==0)//开关闹钟键
{
delay(300);
if(K4==0)
{
while(!
K4);
flag_P=1;
alarm_on=~alarm_on;
}
}
if(flag_P&&K1==1&&K3==1&&K2==1&&K4==1)//释放
{
di();
flag_P=0;
}
return;
}
///******************算法24小时制*******************//
voidcalculate(void)
{
time[0]=hour/10;//时十位
time[1]=hour%10;//时个
time[2]=min/10;//分十位
time[3]=min%10;//分个
time[4]=yue/10;//月十位
time[5]=yue%10;//月个位
time[6]=tian/10;//天十位
time[7]=tian%10;//天个位
time[8]=nhour/10;//闹时十位
time[9]=nhour%10;//闹时个
time[10]=nmin/10;//闹分十位
time[11]=nmin%10;//闹分个
return;
}
voidClock_time(void)//显示闹钟
{
if((counts==0||counts==6||counts==7)||flag_M)
{
nmin=read_24c02(5);//先读出闹分
P2=0xfE;
P0=dispcode[time[11]];//段显闹分个位
P0&=0x7f;//加小数点,代表闹钟模式
delay(50);//延时
P0=0xff;//消隐
P2=0xfD;
P0=dispcode[time[10]];//段显闹分十位
delay(50);//延时
P0=0xff;//消隐
}
if((counts==0||counts==5||counts==7)||flag_M)
{
nhour=read_24c02(6);//先读出闹时
P2=0xFB;
if(alarm_on==1)
{
P0=dispcode[time[9]];//闹时个位
P0&=0x7f;//加固定的一点
}
else
{
P0=dispcode[time[9]];//闹时个位
}
dian=0;//加固定的两点
delay(50);//延时
P0=0xff;//消隐
P2=0xF7;
P0=dispcode[time[8]];//段显闹时十位
delay(50);//延时
P0=0xff;//消隐
}
return;
}
voidRiQi_time(void)//显示日期
{
if((counts==0||counts==4||counts==7)||flag_M)
{
tian=read_24c02(3);//先读出天
P2=0xfE;
P0=dispcode[time[7]];//段显天个位
delay(50);//延时
P0=0xff;//消隐
P2=0xfD;
P0=dispcode[time[6]];//段显天十位
delay(50);//延时
P0=0xff;//消隐
}
if((counts==0||counts==3||counts==7)||flag_M)
{
yue=read_24c02(4);//先读出月
P2=0xFB;
P0=dispcode[time[5]];//月个位
dian=1;
P0&=0x7f;
delay(50);//延时
P0=0xff;//消隐
P2=0xF7;
P0=dispcode[time[4]];//段显月十位
delay(50);//延时
P0=0xff;//消隐
}
return;
}
voidLED_time(void)//显示时间
{
if(counts==0||counts==2||counts==7||flag_M)
{
min=read_24c02
(2);//先读出分钟
P2=0xfE;
P0=dispcode[time[3]];//段显分钟个位
delay(50);//延时
P0=0xff;//消隐
P2=0xfD;
P0=dispcode[time[2]];//段显分钟十位
delay(50);//延时
P0=0xff;//消隐
}
if(counts==0||counts==1||counts==7||flag_M)
{
hour=read_24c02
(1);
P2=0xfB;
P0=dispcode[time[1]];//小时的个位
if(hsec<50)
dian=0;
else
dian=1;
delay(50);//延时
P0=0xff;//消隐
P2=0xf7;
P0=dispcode[time[0]];//段显小时十位
delay(50);//延时
P0=0xff;//消隐
}
return;
}
voidLED_temp(void)//显示温度
{
P2=0xfE;
P0=dispcode[dispbuf[0]];//显c
delay(50);//延时
P0=0xff;//消隐
P2=0xfD;
P0=dispcode[dispbuf[1]];//段显
delay(50);//延时
P0=0xff;//消隐
P2=0xfB;
P0=dispcode[dispbuf[2]];
P0&=0x7f;//加小数点
dian=1;//关两点
delay(50);//延时
P0=0xff;//消隐
P2=0xf7;
P0=dispcode[dispbuf[3]];//段显
delay(50);//延时
P0=0xff;//消隐
return;
}
voidMod_flash(void)
{
uchark;
TR0=1;
ET0=0;
if(TF0)
{
flm++;
TL0=0xF3;//10MS
TH0=0xD8;
TF0=0;
}
if(flm==100)
{
flm=0;
}
k=flm/50;//闪烁频率
if(k==0||k==2)
{flag_M=1;}
else
flag_M=0;
return;
}
voidow_reset(void)
{
charpresence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();//从高拉倒低
DQ=0;
delay(50);//550us
DQ=1;
delay(6);//66us
presence=DQ;//presence=0复位成功,继续下一步
}
delay(45);//延时500us
presence=~DQ;
}
DQ=1;//拉高电平
}
voidwrite_byte(ucharval)
{
uchari;
for(i=8;i>0;i--)//在15~60ms之间对数据线进行采样,如果是高电平就写1,低写0发生。
{
DQ=1;_nop_();_nop_();//在开始另一个写周期前必须有1Us以上的高电平恢复期。
DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DQ=val&0x01;//最低位移出
delay(6);//66us
val=val/2;//右移1位
}
delay
(1);
}
ucharread_byte(void)
{
uchari;
ucharvalue=0;
for(i=8;i>0;i--)
{
DQ=1;//给脉冲信号
_nop_();_nop_();
value>>=1;
DQ=0;//给脉冲信号
_nop_();_nop_();_nop_();_nop_();_nop_();//4us
DQ=1;_nop_();_nop_();_nop_();_nop_();_nop_();//5us
if(DQ)
{value|=0x80;}
delay(13);//66us注意延时的长短,如果是delay(6)会造成LED闪烁
}
DQ=1;
return(value);
}
voidSetting_DS18B20(void)
{
ow_reset();
write_byte(0xCC);//跳过读序号列号的操作
write_byte(0x4e);
write_byte(0x64);
write_byte(0x8a);//-10
write_byte(0x7f);
}
/*读取温度并完成转化*/
voidRead_Temperature(void)
{
uchartplsb,tpmsb;//温度值低位、高位字节
ucharflag=0;
//unsignedintj=0;//暂存计算得温度的整数部分
floattt;
ow_reset();
write_byte(0xCC);//跳过读序号列号的操