📄 16x16温度时钟.c
字号:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit beep=P3^3;
sbit clk=P3^4;
sbit io=P3^5;
sbit rst=P3^6;
sbit k1=P3^0;
sbit k2=P3^1;
sbit ds=P3^2; //DS18B20的端口
char shi,fen,miao;
char month,week,date;
int year;
uchar k1num,f1,miao1,count,s,y0,t2;
uint temp;
float tt;
uint p;
uint code text1[10][32]={ //任意取模软件纵向取模//
{/*---------------年----------------*/
0x00,0x30,0x04,0x30,0x0C,0x30,0x3B,0xF0,0xF3,0xF0,0xF3,0x30,0x33,0x30,0x33,0x30,
0x3F,0xFE,0x3F,0xFE,0x33,0x30,0x33,0x30,0x33,0x30,0x30,0x30,0x00,0x30,0x00,0x00,},
{/*---------------月----------------*/
0x00,0x00,0x00,0x02,0x00,0x0E,0x7F,0xFC,0x7F,0xF0,0x64,0xC0,0x64,0xC0,0x64,0xC0,
0x64,0xC0,0x64,0xC4,0x64,0xC6,0x7F,0xFE,0x7F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,},
{/*---------------日----------------*/
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0xFF,0xFE,0xC3,0x0C,0xC3,0x0C,0xC3,0x0C,
0xC3,0x0C,0xC3,0x0C,0xC3,0x0C,0xFF,0xFE,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,},
{/*---------------时----------------*/
0x7F,0xF8,0x7F,0xF8,0x63,0x30,0x63,0x30,0x7F,0xF8,0x7F,0xF8,0x00,0x00,0x19,0x00,
0x19,0xC0,0x18,0xC0,0x18,0x06,0xFF,0xFE,0xFF,0xFC,0x18,0x00,0x18,0x00,0x00,0x00,},
{/*---------------分----------------*/
0x00,0x00,0x03,0x04,0x06,0x06,0x0F,0x0C,0x1B,0x18,0x73,0xF0,0x63,0xE0,0x03,0x00,
0x03,0x06,0x73,0x06,0x7B,0xFC,0x1F,0xF8,0x0E,0x00,0x07,0x00,0x02,0x00,0x00,0x00,},
{/*---------------秒----------------*/
0x00,0x10,0x36,0x38,0x36,0xE0,0x3F,0xFE,0x7F,0xFE,0x66,0x60,0x01,0xA4,0x0F,0x86,
0x0E,0x06,0x00,0x0C,0xFF,0x98,0xFF,0xB0,0x18,0xE0,0x1E,0xC0,0x06,0x00,0x00,0x00,},
{/*---------------周----------------*/
0x00,0x06,0x00,0x1C,0x7F,0xF8,0x7F,0xE0,0x60,0x00,0x6B,0x78,0x6B,0x78,0x7F,0x58,
0x7F,0x58,0x6B,0x78,0x6B,0x78,0x60,0x06,0x7F,0xFE,0x7F,0xFC,0x00,0x00,0x00,0x00,},
{/*---------------度----------------*/
0x00,0x06,0x7F,0xFE,0x7F,0xF8,0x60,0x02,0x6C,0x62,0x6C,0x66,0x7F,0x76,0xFF,0x7C,
0xED,0x6C,0x6D,0x6C,0x7F,0x7E,0x7F,0x76,0x6C,0x62,0x6C,0x02,0x00,0x00,0x00,0x00,},
{/*---------------温----------------*/
0x08,0x0C,0x4C,0x3C,0x66,0xF0,0x30,0x06,0x00,0xFE,0x7E,0xFE,0x7E,0xC6,0x6A,0xFE,
0x6A,0xC6,0x6A,0xC6,0x6A,0xFE,0x7E,0xC6,0x7E,0xFE,0x00,0xFE,0x00,0x06,0x00,0x00,},
{/*---------------C----------------*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x24,0x00,0x24,0x00,0x18,0x00,
0x00,0x00,0x0F,0xF0,0x10,0x08,0x20,0x04,0x20,0x04,0x20,0x04,0x10,0x08,0x0C,0x30,},
};
uint code text2[11][16]={//任意取模软件纵向取模//
{/*---------------00--------------*/
0x00,0x00,0x0F,0xF0,0x1F,0xF8,0x10,0x08,0x10,0x08,0x1F,0xF8,0x0F,0xF0,0x00,0x00},
{/*---------------01----------------*/
0x00,0x00,0x08,0x00,0x08,0x00,0x1F,0xF8,0x1F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00},
{/*---------------02----------------*/
0x00,0x00,0x0C,0x38,0x1C,0x78,0x10,0xC8,0x11,0x88,0x1F,0x08,0x0E,0x08,0x00,0x00},
{/*---------------03----------------*/
0x00,0x00,0x08,0x10,0x18,0x18,0x11,0x08,0x11,0x08,0x1F,0xF8,0x0E,0xF0,0x00,0x00},
{/*---------------04----------------*/
0x00,0x00,0x00,0x60,0x01,0xE0,0x07,0xA0,0x0E,0x20,0x1F,0xF8,0x1F,0xF8,0x00,0x00},
{/*---------------05----------------*/
0x00,0x00,0x1F,0x90,0x1F,0x98,0x11,0x08,0x11,0x08,0x11,0xF8,0x10,0xF0,0x00,0x00},
{/*---------------06----------------*/
0x00,0x00,0x0F,0xF0,0x1F,0xF8,0x11,0x08,0x11,0x08,0x19,0xF8,0x08,0xF0,0x00,0x00},
{/*---------------07----------------*/
0x00,0x00,0x10,0x00,0x10,0x38,0x11,0xF8,0x17,0xC0,0x1E,0x00,0x18,0x00,0x00,0x00},
{/*---------------08----------------*/
0x00,0x00,0x0E,0xF0,0x1F,0xF8,0x11,0x08,0x11,0x08,0x1F,0xF8,0x0E,0xF0,0x00,0x00},
{/*---------------09----------------*/
0x00,0x00,0x0F,0x10,0x1F,0x98,0x10,0x88,0x10,0x88,0x1F,0xF8,0x0F,0xF0,0x00,0x00},
{/*---------------日----------------*/
0x00,0x00,0x7F,0xff,0x7F,0xff,0x61,0x86,0x61,0x86,0x61,0x86,0x7f,0xff,0x7f,0xff},
};
void delay(uint z)
{uint x,l;
for(x=z;x>0;x--)
for(l=100;l>0;l--);
}
void sfm(uchar aaa) //具体时间日期的显示//
{
uint m1,s,sh,ge;
sh=aaa/16;
ge=aaa%16;
for(m1=8;m1<16;m1++)/*扫描的次数 */
{
P1=m1;/*打开列扫描 */
P0=text2[ge][s];/*送上半部代码 */
s++;/*调 整 */
P2=text2[ge][s];/*送下半部分代码 */
s++;
if(s==16) s=0;
delay(1);
P0=0;
P2=0;
}
for(m1=0;m1<8;m1++)
{ P1=m1;/*打开列扫描 */
P0=text2[sh][s];/*送上半部代码 */
s++;/*调 整 */
P2=text2[sh][s];/*送下半部分代码 */
s++;
if(s==16) s=0;
delay(1);
P0=0;
P2=0;
}
}
void text(uchar bbb) //年月日时分秒周字的显示//
{
uint m1,s;
for(m1=0;m1<16;m1++)/*扫描的次数 */
{
P1=m1;/*打开列扫描 */
P0=text1[bbb][s];/*送上半部代码 */
s++;/*调 整 */
P2=text1[bbb][s];/*送下半部分代码 */
s++;
if(s==32) s=0;
delay(1);
P0=0;
P2=0;
}
}
void week1(uchar ccc) //星期几的显示//
{
uint m1,s,ge;
ge=ccc%16;
if(ge==7)
{for(m1=0;m1<8;m1++)
{ P1=m1;/*打开列扫描 */
P0=text2[10][s];/*送上半部代码 */
s++;/*调 整 */
P2=text2[10][s];/*送下半部分代码 */
s++;
if(s==16) s=0;
delay(1);
P0=0;
P2=0;
}
}
else
{
for(m1=0;m1<8;m1++)
{ P1=m1;/*打开列扫描 */
P0=text2[ge][s];/*送上半部代码 */
s++;/*调 整 */
P2=text2[ge][s];/*送下半部分代码 */
s++;
if(s==16) s=0;
delay(1);
P0=0;
P2=0;
} }
}
void wd(uint ddd) //显示温度//
{
uint m1,s,sh,ge;
sh=ddd/100;
ge=ddd%100/10;
for(m1=8;m1<16;m1++)/*扫描的次数 */
{
P1=m1;/*打开列扫描 */
P0=text2[ge][s];/*送上半部代码 */
s++;/*调 整 */
P2=text2[ge][s];/*送下半部分代码 */
s++;
if(s==16) s=0;
delay(1);
P0=0;
P2=0;
}
for(m1=0;m1<8;m1++)
{ P1=m1;/*打开列扫描 */
P0=text2[sh][s];/*送上半部代码 */
s++;/*调 整 */
P2=text2[sh][s];/*送下半部分代码 */
s++;
if(s==16) s=0;
delay(1);
P0=0;
P2=0;
}
}
/***********************************
DS1820相关
**********************************/
void dsinit()
{
uint i;
ds=0;
i=103;
while(i>0)i--;
ds=1;
i=4;
while(i>0)i--;
}
bit readbit()
{
uint i;
bit datas;
ds=0;i++;
ds=1;i++;i++;
datas=ds;
i=8;while(i>0)i--;
return(datas);
}
uchar read()
{
uchar i,j,datas;
datas=0;
for(i=1;i<=8;i++)
{
j=readbit();
datas=(j<<7)|(datas>>1);
}
return(datas);
}
void writbyte(uchar datas)
{
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=datas&0x01;
datas=datas>>1;
if(testb)
{
ds=0;
i++;i++;
ds=1;
i=8;while(i>0)i--;
}
else
{
ds=0;
i=8;while(i>0)i--;
ds=1;
i++;i++;
}
}
}
void tempconvert()
{
dsinit();
delay(1);
writbyte(0xcc);
writbyte(0x44);
}
uint readtemp()
{
uchar a,b;
dsinit();
delay(1);
writbyte(0xcc);
writbyte(0xbe);
a=read();
b=read();
temp=b;
temp<<=8;
temp=temp|a;
tt=temp*0.0625;
temp=tt*10;
return temp;
}
/******************
函 数 名:RTInputByte()
功 能:实时时钟写入一字节
说 明:往DS1302写入1Byte数据 (内部函数)
入口参数:d 写入的数据
返 回 值:无
**********************/
void RTInputByte(uchar d)
{
uchar h;
ACC = d;
for(h=8; h>0; h--)
{
io = ACC0; /*相当于汇编中的 RRC */
clk = 1;
clk = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
函 数 名:RTOutputByte()
功 能:实时时钟读取一字节
说 明:从DS1302读取1Byte数据 (内部函数)
入口参数:无
返 回 值:ACC
***********************************************************************/
uchar RTOutputByte(void)
{
uchar h;
for(h=8; h>0; h--)
{
ACC = ACC >>1; /*相当于汇编中的 RRC */
ACC7 = io;
clk = 1;
clk = 0;
}
return(ACC);
}
/********************************************************************
函 数 名:W1302()
功 能:往DS1302写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址, ucData: 要写的数据
返 回 值:无
***********************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
rst = 0;
clk = 0;
rst = 1;
RTInputByte(ucAddr); // 地址,命令
RTInputByte(ucDa); //写1Byte数据
clk = 1;
rst = 0;
}
/********************************************************************
函 数 名:R1302()
功 能:读取DS1302某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: DS1302地址
返 回 值:ucData :读取的数据
***********************************************************************/
uchar R1302(uchar ucAddr)
{
uchar ucData;
rst = 0;
clk = 0;
rst = 1;
RTInputByte(ucAddr); /* 地址,命令 */
ucData = RTOutputByte(); /* 读1Byte数据 */
clk = 1;
rst = 0;
return(ucData);
}
/********************************************************************
函 数 名:Set1302()
功 能:设置初始时间
说 明:先写地址,后读命令/数据(寄存器多字节方式)
调 用:W1302()
入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年
7Byte (BCD码)1B 1B 1B 1B 1B 1B 1B
返 回 值:无
***********************************************************************/
/*void Set1302(uchar *pClock)
{
uchar h;
uchar ucAddr = 0x80;
W1302(0x8e,0x00); // 控制命令,WP=0,写操作?
for(h =7; h>0; h--)
{
W1302(ucAddr,*pClock); // 秒 分 时 日 月 星期 年
pClock++;
ucAddr +=2;
}
W1302(0xc0,0x01);
W1302(0XC2,0X03);
W1302(0x8e,0x80); // 控制命令,WP=1,写保护
} */
/******************读取DS1302中的时间****************/
void du1302()
{
// uchar yy;
miao=R1302(0x81); //读取 秒 分 时 日 月 星期 年
fen=R1302(0x83);
shi=R1302(0x85);
/* shi=shi/16*10+shi%16;
fen=fen/16*10+fen%16;
miao=miao/16*10+miao%16;*/
date=R1302(0x87);
month=R1302(0x89);
week=R1302(0x8b);
year=R1302(0x8d);
}
void key()
{
if(k1==0) //k1是调整键,按下后调整的位会闪烁。
{
delay(15);
if(k1==0)
{
beep=0;
delay(100);
beep=1;
count=0;
k1num++;
if(k1num==8)
{
k1num=0;
count=0;
beep=0;
delay(100);
beep=1;
delay(100);
beep=0;
delay(100);
beep=1;
}
}
while(!k1);
}
if(k1num!=0)
{if(k2==0) //按K2是加时间
{
delay(15);
if(k2==0)
{
beep=0;
delay(100);
beep=1;
count=0;
switch(k1num)
{
case 7:
{
miao=0;
W1302(0x8e,0x00);
W1302(0x80,0);
W1302(0x8e,0x80);
}break;
case 6:
{
fen=fen/16*10+fen%16;
fen++;
if(fen==60)fen=0;
fen=fen/10*16+fen%10;
W1302(0x8e,0x00);
W1302(0x82,fen);
W1302(0x8e,0x80);
}break;
case 5 :
{
shi=shi/16*10+shi%16;
shi++;
if(shi==24)shi=0;
shi=shi/10*16+shi%10;
W1302(0x8e,0x00);
W1302(0x84,shi);
W1302(0x8e,0x80);
}break;
case 2:
{ month=month/16*10+month%16;
month++;
if(month==13)month=1;
month=month/10*16+month%10;
W1302(0x8e,0x00);
W1302(0x88,month);
W1302(0x8e,0x80); }
break;
case 3:
{ date=date/16*10+date%16;
date++;if(date>31)date=1;
date=date/10*16+date%10;
W1302(0x8e,0x00);
W1302(0x86,date);
W1302(0x8e,0x80); }
break;
case 4:
{ week=week/16*10+week%16;
week++;if(week==8)week=1;
week=week/10*16+week%10;
W1302(0x8e,0x00);
W1302(0x8a,week);
W1302(0x8e,0x80); }
break;
case 1:
{ year=year/16*10+year%16;
year++;if(year>99)year=0;
year=year/10*16+year%10;
W1302(0x8e,0x00);
W1302(0x8c,year);
W1302(0x8e,0x80); }
break;
/* case 8:
{
shi=shi/16*10+shi%16;
if(shi>12)
shi=shi-12;
if(shi==0)shi=12; /******12/24小时制转换
shi=shi/10*16+shi%10;
} */
case 8:
k1num=0;
break;
default:
break;
}
while(!k2);
}
}}
}
dis()
{
if(miao1>=0&&miao1<1)
{text(8);}
if(miao1>=1&&miao1<2)
{text(7);}
if(miao1>=2&&miao1<3)
{wd(p);}
if(miao1>=3&&miao1<4)
{text(9);}
if(miao1>=5&&miao1<6)
{sfm(year);}
if(miao1>=6&&miao1<7)
{text(0);}
if(miao1>=7&&miao1<8)
{sfm(month);}
if(miao1>=8&&miao1<9)
{text(1);}
if(miao1>=9&&miao1<10)
{sfm(date);}
if(miao1>=10&&miao1<11)
{text(2);}
if(miao1>=11&&miao1<12)
{text(6);}
if(miao1>=12&&miao1<13)
{week1(week);}
if((miao1>=14&&miao1<15)||(miao1>=21&&miao1<22))
{sfm(shi);}
if((miao1>=15&&miao1<16)||(miao1>=22&&miao1<23))
{text(3);}
if((miao1>=16&&miao1<17)||(miao1>=23&&miao1<24))
{sfm(fen);}
if((miao1>=17&&miao1<18)||(miao1>=24&&miao1<25))
{text(4);}
if((miao1>=18&&miao1<19)||(miao1>=25&&miao1<26))
{sfm(miao);}
if((miao1>=19&&miao1<20)||(miao1>=26&&miao1<27))
{text(5);}
}
void main()
{
TMOD=0x01; //16位定时
TH0=(65536-50000)/256; //50ms晶振为12M
TL0=(65536-50000)%256;
EA=1;
TR0=1;
ET0=1;
P2=0xff;
beep=0;
delay(300); //开机滴一声
beep=1;
W1302(0x90,0xaa); //打开涓流充电
while(1)
{
tempconvert();//温度转换
key();
du1302(); //获取时间
p=readtemp(); //读取温度
dis();
}
}
void timer_1(void) interrupt 1 //中断入口,闪烁
{
TH0=(65536-50000)/256; //50ms晶振为12M
TL0=(65536-50000)%256;
if(count++==20) //1000ms
{ count=0;
if(f1++==18) //12秒后进入正常走时。
{k1num=0;}
if(miao1++==28)
{miao1=0;}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -