资源描述
单片机软件实现数码时钟,可以用proteus7.12仿真,也可以,做成实物后18B20会读取出错,或者给我发邮件给你一份实物能用的(proteus7.12仿真18B20会读取出错),电路图不清晰处理方法,将电路图另存为图片格式,或者直接放大即可。
email:liu4153@
#include <reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar hour,min,sec,sec1=0;//时钟函数
uint time_ms=0;
uchar time_sec=0,time_min=34,time_hour=9;
uchar move=1;//调整位位移
bit f0=0,f1=0,f2=0; //f1 键set按下
uchar d7,d6,d5,d4,d3,d2,d1,d0;
uchar key_press;
uint temp;
uchar tempreadbyte(void);
//uint get_temp();
float f_temp;
bit tempreadbit(void);
sbit DataPortDS1820=P3^5; //温度传感器信号线
void tempwritebyte(uchar dat);
void tempchange(void);
void get_temp();
void conv();
void delay(uint z);
void itnt();
void itnttime();
void key_input();
void key_account();
void set();//调整子程序
void adj();//调整子程序
void disp_temperature();
void time_count(); //软件实现时间计算
void Delay15us(void);
void Delay10us(void);
bit RstDS1820(void);
void WriteDS1820(unsigned char ch);
void Delay1us(unsigned char us);
unsigned char ReadDS1820(void);
void SkipROMCode(void);
void StartADC(void) ;
unsigned int GetTempValue(void);
void itnt_18B20(void);
void main()
{
itnt();
while(1)
{
key_account();
}
}
void itnt()//寄存器初始化
{
TMOD = 0x11;
TH0 = (65536-2700)/256;
TL0 = (65536-2700)%256;
TH1 = (65536-54000)/256;
TL1 = (65536-54000)%256;
TR1 = 1;
ET1 = 1;
ET0 = 1;
TR0 = 1;
EA = 1;
}
void delay (uint z)
{
uint x,y;
for (x=z;x>0;x--)
for(y=110;y>0;y--)
{;}
}
void key_account()
{
key_input();
if (key_press==0x0e)
{
delay(100);
key_input();
if(key_press==0x0e)
{
f1=1;
while(key_press==0x0e)
key_input();
set();
move=1;
}
}
if (key_press==0x07)
{
delay(200);
key_input();
if(key_press==0x07)
{
while(key_press==0x07)
key_input();
f0=1;
}
}
while(f0)
{
key_input();
disp_temperature();
if (key_press==0x07)
{
delay(200);
key_input();
if(key_press==0x07)
{
while(key_press==0x07)
key_input();
f0=0;
}
}
}
}
void key_input()
{
key_press=P1;
key_press=key_press&0x0f;
if(key_press!=0x0f)
sec1=0;
}
void set()//调整子程序
{
while(f1)
{
// conv();
key_input();
switch(key_press)
{
case 0x0e: //S1
{
if(key_press==0x0e)
{
delay(100);
key_input();
if(key_press==0x0e)
{
while(key_press==0x0e)
key_input();
f1=0;
if (hour>=24)
{
hour=0;
time_hour=0;
}
}
}
}
break;
case 0x0d://s2
{
if(key_press==0x0d)
{
delay(100);
key_input();
while(key_press==0x0d)
key_input();
move++;
if(move>4)
move=1;
}
}
break;
case 0x0b://s3
{
if(key_press==0x0b)
{
delay(100);
key_input();
while(key_press==0x0b)
key_input();
move--;
if(move<=0)
move=4;
}
}
break;
case 0x07://s4
{
if(key_press==0x07)
{
delay(100);
key_input();
while(key_press==0x07)
key_input();
adj();
}
}
break;
}
}
}
//uchar year,month,day,week,hour,min,sec;//时钟函数
/********************************************************************
函 数 名:adj()
功 能:位调整子程序
说 明:
入口参数:
返 回 值:无
**********************************************************************/
void adj()//位调整子程序
{
uchar ge,shi;
switch(move)
{
case 1:
{
ge = min%10+1;
shi = min/10%10;
if (ge>=10) ge = 0;
min = shi*10+ge;
}
break;
case 2:
{
ge = min%10;
shi = min/10%10+1;
if (shi>=6) shi = 0;
min = shi*10+ge;
}
break;
case 3:
{
ge = hour%10+1;
shi = hour/10%10;
if (shi==2)
{
if (ge>=4) ge=0;
}
if (ge>=10) ge = 0;
hour = shi*10+ge;
}
break;
case 4:
{
ge = hour%10;
shi = hour/10%10+1;
if (shi>=3) shi = 0;
hour = shi*10+ge;
}
break;
}
}
/************************************/
/* 中断显示 */
unsigned char code table[ ] = {//段选
0x3F,0x06,0x5B,0x4F,//0,1,2,3
0x66,0x6D,0x7D,0x07,//4,5,6,7
0x7F,0x6F,0x77,0x7C,//8,9,a,b
0x39,0x5E,0x40,0x00};//c,d,-,关
unsigned char code table1[ ] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选(从低到高)
unsigned int coruscate,wei,dot;
unsigned char d07,d06,d05,d04,d03,d02,d01,d00;
void conv()
{ uint t;
TR0 =0;
if(f0==0)
{
d0 =table[sec%10];
d1 =table[sec/10%10];
d2 =table[14];
d3 =table[min%10];
d4 =table[min/10%10];
d5 =table[14];
d6 =table[hour%10];
d7 =table[hour/10%10];
}
else
{
t = temp;
d0 =0x39;
d1 =0x63;
d2 =table[t%10];
d3 =table[t/10%10]|0x80;
if (f2==0)
{
if (t<100)
d4 = 0;
else d4 =table[t/100%10];
if (t<1000)
d5 = 0;
else d5 =table[t/1000%10];
}
else
{
if (t<100)
{
d4 = 0x40;
d5 = 0;
}
else
{
d4 =table[t/100%10];
d5 =0x40;
}
}
d6 =0;
d7 =0;
// d7 = table[sec1%10];
}
TR0 =1;
}
void t0(void) interrupt 1
{
TH0=(65536-2700)/256; //2.5ms
TL0=(65536-2700)%256;
conv();
d00=d0;
d01=d1;
d02=d2;
d03=d3;
d04=d4;
d05=d5;
d06=d6;
d07=d7;
if(f1==1)
{
coruscate++;
if(coruscate>=100)
coruscate=0;
if(coruscate<50)
{
switch(move)
{
/*case 1: d03=0xf; break;
case 2: d04=0xf; break;
case 3: d06=0xf; break;
case 4: d07=0xf; break;*/
case 1: d03=0; break;
case 2: d04=0; break;
case 3: d06=0; break;
case 4: d07=0; break;
}
}
}
else
{
d00=d0;
d01=d1;
d02=d2;
d03=d3;
d04=d4;
d05=d5;
d06=d6;
d07=d7;
}
wei++;
if(wei>8)
wei=1;
switch(wei)
{
case 1:
{
P0=0;
P2=table1[0];
P0=d00;
}
break;
case 2:
{
P0=0;
P2=table1[1];
P0=d01;
}
break;
case 3:
{
P0=0;
P2=table1[2];
P0=d02;
}
break;
case 4:
{
P0=0;
P2=table1[3];
P0=d03;
}
break;
case 5:
{
P0=0;
P2=table1[4];
P0=d04;
}
break;
case 6:
{
P0=0;
P2=table1[5];
P0=d05;
}
break;
case 7:
{
P0=0;
P2=table1[6];
P0=d06;
}
break;
case 8:
{
P0=0;
P2=table1[7];
P0=d07;
}
break;
}
}
/******************************************/
/*软件实现时间计算*/
/******************************************/
void t1(void) interrupt 3
{
TH1 = (65536-54000)/256;
TL1 = (65536-54000)%256;
time_ms++;
if(time_ms>=20)
{
time_ms=0;
if(f1==0)
{
time_sec++;
if(time_sec>=60)
{
time_sec=0;
time_min++;
if(time_min%10==0|time_min%10==5)
{ f0=1;sec1=0; }
if(time_min>=60)
{
time_min=0;
time_hour++;
if(time_hour>=24)
time_hour=0;
}
}
sec=time_sec;
min=time_min;
hour=time_hour;
}
if(f1==1)
{
time_sec=0;
sec=0;
time_min=min;
time_hour=hour;
}
if(f1==1)
{
sec1++;
if(sec1>=10) //按键无响应退出设置时间调整
f1=0;
}
if(f0==1)
{
sec1++;
if(sec1>=5) //按键无响应退出设置时间调整
f0=0;
}
}
}
/******************************************/
/*18B20相关程序*/
/******************************************/
void disp_temperature()
{
uint i;
delay(100);
while(i>0)i--;
temp=GetTempValue(); //读取温度值
}
void Delay15us(void)
{
Delay1us(15);
}
void Delay10us(void)
{
Delay1us(10);
}
bit RstDS1820(void) //返回0-有设备连接1-无设备连接
{
unsigned char i;
bit RstFlag;
RstFlag=1;
DataPortDS1820=0;
for (i=0;i<100/*40*/;i++) //480us
Delay15us();
DataPortDS1820=1;
for (i=0;i<4;i++) //15us-60us
{
Delay15us();
}
for (i=0;i<16;i++) //60us-240us
{
Delay15us();
if (DataPortDS1820==0) RstFlag=0;
}
for (i=0;i<16;i++) //240us
{
Delay15us();
}
return RstFlag;
}
void WriteDS1820(unsigned char ch)
{
unsigned char i;
DataPortDS1820=1;
Delay1us(1);
for (i=0;i<8;i++)
{
EA=0;
DataPortDS1820=0;
Delay15us();
DataPortDS1820=ch&0x1;
EA=1;
Delay15us();Delay15us();Delay15us();
DataPortDS1820=1;
ch=ch>>1;
Delay1us(1);
}
}
void Delay1us(unsigned char us)
{
while (us)
{
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
--us;
}
}
unsigned char ReadDS1820(void)
{
unsigned char i,ch;
ch=0;
DataPortDS1820=1;
Delay1us(1);
for (i=0;i<8;i++)
{
EA=0;
DataPortDS1820=0;
Delay10us();
DataPortDS1820=1;
Delay1us(2);
ch=ch>>1;
if (DataPortDS1820==1)
{
ch=ch+0x80;
}
EA=1;
Delay15us();Delay15us();Delay15us();
}
return ch;
}
void SkipROMCode(void)
{
RstDS1820();
WriteDS1820(0xcc);
}
void StartADC(void)
{
RstDS1820(); //复位
WriteDS1820(0xcc); //
WriteDS1820(0x44); //启动AD转换 12bit700ms
}
unsigned int GetTempValue(void)
{
unsigned char i,j;
unsigned int T;
SkipROMCode();
WriteDS1820(0xBE);
i=ReadDS1820();
j=ReadDS1820();
StartADC();
T=i+j*256;
if (T>0xFC8F)
{
T=~T+1;
f2=1;
}
else f2=0;
T=T*0.0625*10;
return (T);
}
展开阅读全文