#include<reg51.h>
#define uchar unsigned char
sbit DQ=P3^7;
sbit voice=P3^0;
sbit light=P3^1;
sbit din=P1^0; //MAX7221数据输入端
sbit cs=P1^1; //MAX7221片选输入端
sbit clk=P1^2;
sbit key_rst=P1^5;
sbit key_min=P1^6;
sbit key_hour=P1^7;
//sbit key_clr=P3^6;
//unsigned int flag;
unsigned int temp;
unsigned char second;
unsigned char minute;
unsigned char hour;
unsigned char dis[4]={0,0,0,0};
unsigned char led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0xff,0xbf};
//分别为0-9,不显示,负号
unsigned char led1[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//带小数点显示
uchar code dispcode[]={
0x7e,0x30,0x6d,0x79, //’0’ ,’1’ ,’2’, ’3’
0x33,0x5b,0x5f,0x70, //’4’ ,’5’, ’6’, ’7’
0x7f,0x7b,0x01,0x00 //’8’, ’9’ ,’-’, 无显示
};
unsigned char str2[8]={" "};
void delay(unsigned int i) //如果i是unsigend char类型,则会出现错误结果
{
while(i--);
}
void Init(void)//初始化
{
//unsigned char flag=0;
DQ = 0; //单片机将DQ拉低
delay(100); //精确延时 大于 480us小于960us
DQ = 1; //拉高总线
delay(30);
//flag=DQ; //稍做延时后 如果flag=0则初始化成功 flag=1则初始化失败
//delay(20);
}
unsigned char Read(void)//读字节
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay(5);
}
return(dat);
}
void Write(unsigned char dat)//写字节
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
}
void Display(unsigned int temp) //显示程序
{
if(temp<=0x0800)
{ temp>>=4; //右移4位,相当于乘0.0625,将温度化为十进制
temp*=10; //扩大10倍,显示一位小数
dis[0]=temp/1000; //千位
dis[1]=temp%1000/100; //百位
dis[2]=temp%1000%100/10; //十位
dis[3]=temp%1000%100%10; //个位
}
else
{
temp=~temp;
temp+=1;
temp>>=4;
dis[0]=0x0c; //负数
dis[1]=temp%100/10; //百位
dis[2]=temp%100%10; //十位
dis[3]=0; //个位
}
P2=0x01; //先片选,在段选,反过来就不能正常显示
P0=led[dis[0]];
delay(200);
delay(200);
P2=0x02;
P0=led[dis[1]];
delay(200);
delay(200);
P2=0x04;
P0=led1[dis[2]];
delay(200);
delay(200);
P2=0x08;
P0=led[dis[3]];
delay(200);
delay(200);
}
void clr_alarm(void)
{
voice=0;
light=1;
}
void set_alarm(void)
{
voice=1;
light=0;
}
void alarm(int temp)
{
//if(flag==0)
// {
if(temp>1500)
{
set_alarm();
}
else
{ voice=0;
light=1;
}
// }
}
void Timer() interrupt 1
{ static uchar numval=20;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
numval--;
if(numval==0)
{
numval=20;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)hour=0;
}
}
str2[0]=hour/10;
str2[1]=hour%10;
str2[3]=minute/10;
str2[4]=minute%10;
str2[6]=second/10;
str2[7]=second%10;
}
}
void Write_7221(uchar com,uchar da)
{
uchar temp,i,j;
cs=0; //片选有效
clk=0; //时钟低
for (i=0;i<8;i++) //发送显示位置
{
temp=com;
if ((temp&(0x80>>i))!=0) //先发高位 依次到低位
din=1;
else din=0;
clk=1; //时钟高 上升沿锁数据
for (j=0;j<5;j++);
clk=0;
}
for (i=0;i<8;i++) //发送数据
{
temp=da;
if ((temp&(0x80>>i))!=0) //先发高位 依次到低位
din=1;
else din=0;
clk=1;
for (j=0;j<5;j++);
clk=0;
}
cs=1;
}
/*******************MAX7221初始化********************/
void Init_MAX7221(void)
{
Write_7221(0x0c,0x01); //正常工作状态,关断模式
Write_7221(0x09,0x00); //译码选择,非BCD码
Write_7221(0x0a,0x0f); //亮度调节
Write_7221(0x0b,0x07); //显示位数
}
void keyscan1(void)
{ if(key_rst==0)
{
hour=0;
minute=0;
second=0;
}
}
void keyscan2()
{ if(key_min==0)
{ while(!key_min );
minute++;
if(minute==60)
{ minute=0; }
}
}
void keyscan3()
{ if(key_hour==0)
{ while(!key_hour);
hour++;
if(hour==24)
{ hour=0; }
}
}
main()
{
unsigned char tl=0,th=0;
clr_alarm();
Init_MAX7221();
hour=22;
minute=33;
second=2;TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
while(1)
{
Write_7221(0x01,dispcode[str2[0]]);
Write_7221(0x02,dispcode[str2[1]]);
Write_7221(0x03,0x01);
Write_7221(0x04,dispcode[str2[3]]);
Write_7221(0x05,dispcode[str2[4]]);
Write_7221(0x06,0x01);
Write_7221(0x07,dispcode[str2[6]]);
Write_7221(0x08,dispcode[str2[7]]);
keyscan1();
keyscan2();
keyscan3();
Init();
Write(0xCC); // 跳过读序号列号的操作
Write(0x44); // 启动温度转换
delay(100);
Init();
Write(0xCC); //跳过读序号列号的操作
Write(0xBE); //读取温度寄存器等
delay(100);
tl=Read(); //读取温度值低位
th=Read(); //读取温度值高位
temp=th<<8;
temp|=tl;
Display(temp);
alarm(temp);
}
}