基于ds1302万年历应用实例、基于ds18b20温度检测应用实例.doc
《基于ds1302万年历应用实例、基于ds18b20温度检测应用实例.doc》由会员分享,可在线阅读,更多相关《基于ds1302万年历应用实例、基于ds18b20温度检测应用实例.doc(13页珍藏版)》请在冰点文库上搜索。
![基于ds1302万年历应用实例、基于ds18b20温度检测应用实例.doc](https://file1.bingdoc.com/fileroot1/2023-5/7/eeaadc70-b6bc-4f13-b3f1-b7563bd6a028/eeaadc70-b6bc-4f13-b3f1-b7563bd6a0281.gif)
基于DS1302万年历以及基于DS18B20的温度检测电路
/***************主程序***************/
#include
#include"LCD1602.h"
#include"1302.h"
#include"wendu.h"
#defineucharunsignedchar
#defineuintunsignedint
sbitspeaker=P2^4;
bitkey_flag1=0,key_flag2=0;
/*ucharshijian[6]={0};*/
//sec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0;
uchardata_alarm[7]={0};
/*********************************键盘控制****************************************************/
intkey_scan()//扫描是否有键按下
{inti=0;
uinttemp;
P1=0xf0;
temp=P1;
if(temp!
=0xf0)
i=1;
else
i=0;
returni;
}
ucharkey_value() //确定按键的值
{
uintm=0,n=0,temp;
ucharvalue;
ucharcodev[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'} ;//用二维数组进行按键查询
P1=0xfe;temp=P1;if(temp!
=0xfe)m=0;
P1=0xfd;temp=P1 ;if(temp!
=0xfd)m=1;
P1=0xfb;temp=P1 ;if(temp!
=0xfb)m=2;
P1=0xf7;temp=P1 ;if(temp!
=0xf7)m=3;
P1=0xef;temp=P1 ;if(temp!
=0xef)n=0;
P1=0xdf;temp=P1 ;if(temp!
=0xdf)n=1;
P1=0xbf;temp=P1 ;if(temp!
=0xbf)n=2;
value=v[m][n];
returnvalue;
}
/************************************************设置闹铃函数*********************************/
voidnaoling(void)
{
uchari=0,l=0,j;
init1602();
while(key_flag2&&i<12)
if(key_scan()){j=key_value();write_data(j);if(i%2==0)data_alarm[l]=((j-'0')<<4);else{data_alarm[l]+=(j-'0');l++;}i++;delay(600);}
write_com(0x01);
}
ucharaccording(void)
{uchark;
if(data_alarm[0]==x[1]&&data_alarm[1]==x[2]&&data_alarm[2]==x[3]&&data_alarm[3]==x[4]&&data_alarm[4]==x[5]&&data_alarm[5]==x[6])
k=1;
elsek=0;
returnk;
}
voidspeak(void)
{uinti=50;
while(i)
{speaker=0;
delay
(2);
speaker=1;
delay
(1);
i--;
}
}
voidalarm(void)
{uinti=10; //i=10
while(i)
{
speak();
delay(10);
i--;
}
}
/************************************修改时间操作****************************************/
voidxiugai(void) //修改时间函数
{
if(key_scan()&&key_flag1)
switch(key_value())
{case'0':
{data1[1]++;if(data1[1]>'9'){data1[1]='0';data1[0]++;}
if(data1[0]>'9'){data1[0]='0';data1[1]='0';}x[1]=(data1[0]-'0')<<4|(data1[1]-'0');dswrite(0x8c,x[1]);}break;
case'1':
{data1[4]++;if(data1[4]>'9'){data1[4]='0';data1[3]++;}
if(data1[3]=='1'&&data1[4]=='3'){data1[3]='0';data1[4]='1';}x[2]=(data1[3]-'0')<<4|(data1[4]-'0');dswrite(0x88,x[2]);}break;
case'2':
{data1[7]++;if(data1[7]>'9'){data1[7]='0';data1[6]++;}
if(data1[6]=='3'&&data1[7]=='2'){data1[6]='0';data1[7]='1';}x[3]=(data1[6]-'0')<<4|(data1[7]-'0');dswrite(0x86,x[3]);}break;
case'3':
{time[1]++;if(time[1]>'9'){time[1]='0';time[0]++;}
if(time[0]=='2'&&time[1]=='4'){time[0]='0';time[1]='0';}x[4]=(time[0]-'0')<<4|(time[1]-'0');dswrite(0x84,x[4]);}break;
case'4':
{time[4]++;if(time[4]>'9'){time[4]='0';time[3]++;}
if(time[3]=='6'&&time[4]=='1'){time[3]='0';time[4]='1';}x[5]=(time[3]-'0')<<4|(time[4]-'0');dswrite(0x82,x[5]);}break;
case'5':
{time[7]++;if(time[7]>'9'){time[7]='0';time[6]++;}
if(time[6]=='6'&&time[7]=='1'){time[6]='0';time[7]='1';}x[6]=(time[6]-'0')<<4|(time[7]-'0');dswrite(0x80,x[6]);}break;
//case'b':
reset();break;
default:
break;
}
}
/************************************************中断处理函数*********************************/
voidchanging(void)interrupt0using0 //需要修改时间和日期,或者停止修改
{
if(key_flag1)key_flag1=0;
elsekey_flag1=1;
}
voidalarming(void)interrupt3using0 //需要设置闹铃或者停止设置
{
if(key_flag2)key_flag2=0;
elsekey_flag2=1;
}
/*********************************主函数*************************************************/
main()
{
uinti;
//uchar*l;
ucharp1[]="D:
",p2[]="TM",p3[]="Wd";
EA=1;
EX0=1;
IT0=1;
EA=1;
EX1=1;
IT1=1;
init1602(); //LCD初始化
Initial_DS1302(); //1302初始化
ds18b20();
baojing=1;//报警灯
while
(1)
{//write_com(0x80); //显示区域不够去除
//write_string(p1,2);
write_com(0x88);
write_string(p3,2);
write_com(0xc0);
write_string(p2,2);
gettime();//从1302中读取时间
datalcd(); //日期显示转换
timelcd(); //时间显示转换
xiugai(); //调用修改时间函数
if(key_flag2)naoling();
if(according())alarm();
write_com(0x80);
write_string(data1,8);
write_com(0xc2);
write_string(time,8);
ds18b20();//12位转换时间最大为750ms
get_temperature();
display();
delay(10);
}
}
/*****1302子程序:
*************/
#ifndef_REAL_TIMER_DS1302_2009_5_20_
#define_REAL_TIMER_DS1302_2003_5_20_
#include
#defineucharunsignedchar
#defineuintunsignedint
voidtimelcd();
voiddatalcd();
sbitDS1302_CLK=P2^6;//实时时钟时钟线引脚
sbitDS1302_IO=P2^7;//实时时钟数据线引脚
sbitDS1302_RST=P2^5;//实时时钟复位线引脚
sbitACC0=ACC^0;
sbitACC7=ACC^7;
ucharx[7]={0x20,0x10,0x04,0x18,0x10,0x0,0x00};//分别存放年月日,时分秒
//ucharx[6]={0};
uchartime[7]={0};//存放时间
uchardata1[7]={0};//存放日期
voiddswrite(unsignedcharadd,unsignedchardat)
{
unsignedchari;
DS1302_CLK=0;
DS1302_RST=0;
DS1302_RST=1;
for(i=0;i<8;i++)
{
DS1302_IO=0;
if(add&0x01)
DS1302_IO=1;
DS1302_CLK=1;
add>>=1;
DS1302_CLK=0;
_nop_();;
}
ACC=dat;
for(i=0;i<8;i++)
{
DS1302_IO=0;
if(dat&0x01)
DS1302_IO=1;_nop_();
DS1302_CLK=1;
DS1302_CLK=0;
dat>>=1;
}
DS1302_CLK=0;
DS1302_RST=0;
}
unsignedchardsread(unsignedcharadd)
{
unsignedchari,dat;
DS1302_CLK=0;
DS1302_RST=0;
DS1302_RST=1;
ACC=add;
for(i=0;i<8;i++)
{
DS1302_IO=0;
if(add&0x01)
DS1302_IO=1;_nop_();
DS1302_CLK=1;
add>>=1;
DS1302_CLK=0;
_nop_();
}
DS1302_IO=1;//送1呈输入状态
dat=0;
for(i=0;i<7;i++)
{
if(DS1302_IO)dat|=0x80;
DS1302_CLK=1;
dat>>=1;_nop_();
DS1302_CLK=0;
_nop_();
}
DS1302_CLK=0;
DS1302_RST=0;
returndat;
}
voidgettime()//从1302中读取时间
{
DS1302_RST=0;
x[1]=dsread(0x8d);//年
x[2]=dsread(0x89);//月
x[3]=dsread(0x87);//日
x[4]=dsread(0x85);//时
x[5]=dsread(0x83);//分
x[6]=dsread(0x81);//秒
}
voiddatalcd()
{
data1[0]=(x[1]>>4)+'0';
data1[1]=((x[1]&0x0f)+'0');
data1[2]='-';
data1[3]=((x[2]>>4)&0x0f)+'0';
data1[4]=(x[2]&0x0f)+'0';
data1[5]='-';
data1[6]=((x[3]>>4)&0x0f)+'0';
data1[7]=(x[3]&0x0f)+'0';
}
voidtimelcd()
{
time[0]=((x[4]>>4)&0x0f)+'0';
time[1]=(x[4]&0x0f)+'0';
time[2]=':
';
time[3]=((x[5]>>4)&0x0f)+'0';
time[4]=(x[5]&0x0f)+'0';
time[5]=':
';
time[6]=((x[6]>>4)&0x0f)+'0';
time[7]=(x[6]&0x0f)+'0';
}
voidDS1302_SetProtect(bitflag)//是否写保护
{
if(flag)
dswrite(0x8E,0x10);
else
dswrite(0x8E,0x00);
}
voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//设置时间函数
{
DS1302_SetProtect(0);
dswrite(Address,((Value/10)<<4|(Value%10)));//将十进制数转换为BCD码
} //在DS1302中的与日历、时钟相关的寄存器存放的数据必须为BCD码形式
voidInitial_DS1302(void)//初始化1302
{
unsignedcharSecond;
Second=dsread(0x80);
if(Second&0x80) //初始化时间
DS1302_SetTime(0x80,0);
}
/**************ds18b20子程序************/
#include
#include
//#include"cd1602.h"
#defineucharunsignedchar
#defineuintunsignedint
voiddisplay();
voiddelay(uintz);
sbitds=P3^7;
sbitbaojing=P3^6;
ucharflag;
uinttemp;//参数temp一定要声明为int型
ucharwendustring[6]={0};//显示温度用
voidTempDelay(ucharus)//延时函数
{
while(us--);
}
voidds_reset(void) //18b20复位
{
ds=1;
_nop_();//延时1us
ds=0;
TempDelay(80); //最少480us
_nop_();
ds=1;
TempDelay(5);//存在检测高电平时间:
15~60us,此处大约延时44us
_nop_();
_nop_();
_nop_();
if(ds==0)
flag=1;//detect18b20success
else
flag=0;//detect18b20fail
TempDelay(20);//存在检测低电平时间:
60~240us,此处延时约140us
_nop_();
_nop_();
ds=1;//拉高总线,让总线处于空闲状态
}
bitds_read_bit(void)//读一位
{
bitdat;
ds=0;
_nop_();//读时隙起始总线拉低至少1us
ds=1;
_nop_();
_nop_();
dat=ds;
TempDelay(10);//所有读"时间隙"必须60~120us,此处延时约77us
return(dat);
}
uchards_read_byte(void)//读一字节
{
ucharvalue,i,j;
value=0;
for(i=0;i<8;i++)
{
j=ds_read_bit();
value=(j<<7)|(value>>1);
}
return(value);//返回一个字节的数据
}
voidds_write_byte(uchardat)//写一个字节
{
uchari;
bitonebit;
for(i=1;i<=8;i++)
{
onebit=dat&0x01; //判断位为0还是1
dat=dat>>1;
if(onebit)//写1
{
ds=0;
_nop_();
_nop_();
ds=1;
TempDelay(5);
}
else//写0
{
ds=0;
TempDelay(8);//写0时间隙,低电平至少60μs,此处大约64us
ds=1;
_nop_();
_nop_();
}
}
}
voidds18b20() //初始化
{
ds_reset();
delay
(1);//约2ms
ds_write_byte(0xcc);
ds_write_byte(0x44);
}
uintget_temperature() //读取温度函数
{
floatwendu;
uchara,b;
ds_reset();
delay
(1);//约2ms
ds_write_byte(0xcc);
ds_write_byte(0xbe);
a=ds_read_byte();
b=ds_read_byte();
temp=b;
temp<<=8;
temp=temp|a;
wendu=temp*0.0625;
temp=wendu*10+0.5;
returntemp;
}
/*voidmain()
{ucharp3[]="W";
init1602();
baojing=1;//报警灯
while
(1)
{
write_com(0x88);
write_string(p3,1);
ds18b20();//12位转换时间最大为750ms
get_temperature();
display();
}
}*/
voiddisplay()
{
if(temp&0x8000)
{
temp=~temp;
temp=temp-575; //负值温度调试用
wendustring[0]='-';
wendustring[1]='0';
wendustring[2]=temp%1000/100+'0';//显示温度用
wendustring[3]=temp%100/10+'0';
if(wendustring[2]>='2'&&wendustring[3]>'5')baojing=0;
elseif(wendustring[2]>='3')baojing=0;
elsebaojing=1;
wendustring[4]='.';
wendustring[5]=temp%10+'0';
}
else
{wendustring[0]='+';
wen