#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,
0x7d,0x07,0x7f,0x6f,0x00,0x80};/*0~9和无显示、的数码管段码*/
uint dd=0,sec=0,min=0,hour=12; //时间初始值12:00:00
uchar sec1=0,min1=0,hour1=0,set=0,sw=0;//闹钟设定初始值0:00:00
uchar x[7],y[7];
uint temp,k; // variable of temperature
uchar flag1;
/*-------引脚定义--------*/
sbit key_sw=P1^0;
sbit set_key=P1^1;
sbit key_up=P1^2;
sbit key_down=P1^3;
sbit LED1=P1^4; //温度显示指示
sbit LED2=P1^5; //时间显示指示
sbit LED3=P1^6; //闹钟显示指示
sbit shu1=P2^0;
sbit shu2=P2^1;
sbit shu3=P2^2;
sbit shu4=P2^3;
sbit shu5=P2^4;
sbit shu6=P2^5;
sbit DS=P2^6; //define interface 定义DS18B20接口
sbit beep=P2^7;//蜂鸣器报警(高电平有效)
/*--------延时子程序--------*/
void delay(uint count) //delay
{
uint i;
while(count)
{
i=200;
while(i>0)
i--;
count--;
}
}
void dsreset(void) //send reset and initialization command
{
uint i; //DS18B20初始化
DS=0;
i=103;
while(i>0)i--;
DS=1;
i=4;
while(i>0)i--;
}
bit tmpreadbit(void) //read a bit 读一位
{
uint i;
bit dat;
DS=0;i++; //i++ for delay 小延时一下
DS=1;i++;i++;
dat=DS;
i=8;
while(i>0)i--;
return (dat);
}
uchar tmpread(void) //read a byte date 读一个字节
{
uchar i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmpreadbit();
dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好//一个字节在DAT里
}
return(dat); //将一个字节数据返回
}
void tmpwritebyte(uchar dat) //write a byte to ds18b20
{ //写一个字节到DS18B20里
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //write 1 写1部分
{
DS=0;
i++;i++;
DS=1;
i=8;
while(i>0)i--;
}
else
{
DS=0; //write 0 写0部分
i=8;while(i>0)i--;
DS=1;
i++;i++;
}
}
}
void tmpchange(void) //DS18B20 begin change 发送温度转换命令
{
dsreset(); //初始化DS18B20
delay(1); //延时
tmpwritebyte(0xcc); // 跳过序列号命令
tmpwritebyte(0x44); //发送温度转换命令
}
uint tmp() //get the temperature 获得温度
{
double tt;
uchar flag1=0;// sign of the result positive or negative
uchar a,b;
dsreset();
delay(1);
tmpwritebyte(0xcc);
tmpwritebyte(0xbe); //发送读取数据命令
a=tmpread(); //连续读两个字节数据low
b=tmpread();//连续读两个字节数据high
if((b&0xf0)!=0x00)//如果高八位与0xf0相与不为0(按位与)
{
flag1=1;a=~a;b=~b;
}
temp=b;
temp<<=8; //two byte compose a int variable
temp=temp|a; //两字节合成一个整型变量。
if(flag1==1)
{temp=temp+1;}
tt=temp*0.0625; //得到真实十进制温度值,因为DS18B20
//可以精确到0.0625度,所以读回数据的最低位代表的是
//0.0625度。
temp=tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位
//也转换为可显示数字,同时进行一个四舍五入操作。
return temp; //返回温度值
}
void display1(uint temp) //显示温度程序
{
uchar A1,A2,A3,A4;
A1=temp/1000; //分离出三位要显示的数字
A2=temp/100%10;
A3=temp/10%10;
A4=temp%10;
if(flag1==1)
{
shu1=0;
P0=0x40;
delay(1);
shu1=1;
}
if(flag1==0)
{
shu1=0;
P0=table[A1];
delay(1);
shu1=1;
}
shu2=0;
P0=table[A2];
delay(1);
shu2=1;
shu3=0;
P0=table[A3];
delay(1);
shu3=1;
shu3=0;
P0=table[11];
delay(1);
shu3=1;
shu4=0;
P0=table[A4];
delay(1);
shu4=1;
}
/*--------定时器T0初始化---------*/
void init_timer0()
{
TMOD=0x11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;ET0=1;EA=1;
}
/*------50ms定时中断服务子函数----*/
void zd0(void)interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
dd++;
if(dd>=20){sec++;dd=0;}//每1000ms,秒单元递增
if(sec>=60){min++;sec=0;}//每60s,分单元递增
if(min>=60){hour++;min=0;}//每60m,时单元递增
if(hour>=24){hour=0;}//每24小时,时单元清零
x[0]=hour/10;x[1]=hour%10;
x[2]=min/10;x[3]=min%10;
x[4]=sec/10;x[5]=sec%10;
}
/*----------键盘扫描-----------*/
void keysm()
{
if(key_sw==0)
{
delay(5);
if(key_sw==0)
{
sw++;
if(sw>=3)sw=0;
}
while(!key_sw);//键盘消抖
delay(5); //键盘消抖
while(!key_sw);//键盘消抖
}
if(set_key==0)
{
delay(5);
if(set_key==0)
{
if((sw==1)||(sw==2))
{
set++;
if(set>=4)set=0;
}
}
while(!set_key);
delay(5);
while(!set_key);
}
if(key_up==0)
{
delay(5);
if(key_up==0)
{
if(sw==1)
{
if(set==1)
{
hour++;
x[0]=hour/10;
x[1]=hour%10;
}
if(set==2)
{
min++;
x[2]=min/10;
x[3]=min%10;
}
if(set==3)
{
sec++;
x[4]=sec/10;
x[5]=sec%10;
}
}
if(sw==2)
{
if(set==1)
{
hour1++;
y[0]=hour1/10;
y[1]=hour1%10;
}
if(set==2)
{
min1++;
y[2]=min1/10;
y[3]=min1%10;
}
if(set==3)
{
sec1++;
y[4]=sec1/10;
y[5]=sec1%10;
}
}
}
while(!key_up);
delay(5);
while(!key_up);
}
if(key_down==0)
{
delay(5);
if(key_down==0)
{
if(sw==1)
{
if(set==1)
{
hour--;
x[0]=hour/10;
x[1]=hour%10;
}
if(set==2)
{
min--;
x[2]=min/10;
x[3]=min%10;
}
if(set==3)
{
sec--;
x[4]=sec/10;
x[5]=sec%10;
}
}
if(sw==2)
{
if(set==1)
{
hour1--;
y[0]=hour1/10;
y[1]=hour1%10;
}
if(set==2)
{
min1--;
y[2]=min1/10;
y[3]=min1%10;
}
if(set==3)
{
sec1--;
y[4]=sec1/10;
y[5]=sec1%10;
}
}
}
while(!key_down);
delay(5);
while(!key_down);
}
}
/*-------显示子函数-------*/
void display(uchar aa,uchar bb,uchar cc,uchar ba,uchar sh,uchar g)
{
if(set==0)
{
shu1=0;
P0=table[aa];
delay(1);
shu1=1;
shu2=0;
P0=table[bb];
delay(1);
shu2=1;
}
if(set==1)
{
shu1=0;
P0=table[aa];
delay(1);
shu1=1;
shu2=0;
P0=table[bb];
delay(1);
shu2=1;
shu3=1;
shu4=1;
shu5=1;
shu6=1;
}
shu2=0;
P0=table[11];
delay(1);
shu2=1;
if(set==0)
{
shu3=0;
P0=table[cc];
delay(1);
shu3=1;
shu4=0;
P0=table[ba];
delay(1);
shu4=1;
}
if(set==2)
{
shu3=0;
P0=table[cc];
delay(1);
shu3=1;
shu4=0;
P0=table[ba];
delay(1);
shu4=1;
shu1=1;
shu2=1;
shu5=1;
shu6=1;
}
shu4=0;
P0=table[11];
delay(1);
shu4=1;
if(set==0)
{
shu5=0;
P0=table[sh];
delay(1);
shu5=1;
shu6=0;
P0=table[g];
delay(1);
shu6=1;
}
if(set==3)
{
shu5=0;
P0=table[sh];
delay(1);
shu5=1;
shu6=0;
P0=table[g];
delay(1);
shu6=1;
shu1=1;
shu2=1;
shu3=1;
shu4=1;
}
}
/*======闹钟======*/
void alarm(void)
{
if((x[0]==y[0])&&(x[1]==y[1])&&(x[2]==y[2])&&(x[3]==y[3])&&(x[4]>=y[4])&&(x[5]>=y[5]))//闹钟
{
k++;
if(k>50)
{
k=0;
beep=~beep;
}
}
else
{
beep=0;
}
}
/*------主函数---------*/
void main()
{
init_timer0();//定时器初始化
while(1)
{
tmpchange(); //温度转换
keysm();//键盘扫描
if(sw==0)
{
display1(tmp()); //显示温度程序
LED1=0;LED2=1;LED3=1;
}
if(sw==1)
{
display(x[0],x[1],x[2],x[3],x[4],x[5]);//显示时间
LED1=1;LED2=0;LED3=1;
}
if(sw==2)
{
display(y[0],y[1],y[2],y[3],y[4],y[5]);//显示闹钟时间
LED1=1;LED2=1;LED3=0;
}
alarm();//闹钟
}
}