基于51单片机的温度上下限控制实时显示时间温度.docx

上传人:b****6 文档编号:8258858 上传时间:2023-01-30 格式:DOCX 页数:23 大小:297.68KB
下载 相关 举报
基于51单片机的温度上下限控制实时显示时间温度.docx_第1页
第1页 / 共23页
基于51单片机的温度上下限控制实时显示时间温度.docx_第2页
第2页 / 共23页
基于51单片机的温度上下限控制实时显示时间温度.docx_第3页
第3页 / 共23页
基于51单片机的温度上下限控制实时显示时间温度.docx_第4页
第4页 / 共23页
基于51单片机的温度上下限控制实时显示时间温度.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

基于51单片机的温度上下限控制实时显示时间温度.docx

《基于51单片机的温度上下限控制实时显示时间温度.docx》由会员分享,可在线阅读,更多相关《基于51单片机的温度上下限控制实时显示时间温度.docx(23页珍藏版)》请在冰豆网上搜索。

基于51单片机的温度上下限控制实时显示时间温度.docx

基于51单片机的温度上下限控制实时显示时间温度

#include"STC89C51RC.H"

#include

#include"ds18b20.h"

#include"lcd1602.h"

#include"ds1302.h"

#include"2402.h"

uchardatadatadis[]={0x00,0x00,0x00,0x00,0x00};

uinttemp=0;

sbitK1=P3^0;

sbitK2=P3^1;

sbitK3=P3^2;

sbitK4=P3^3;

sbitK5=P3^7;

sbitL1=P1^6;

sbitL2=P1^7;

sbitled=P2^7;

sbitspeaker=P1^0;

ucharkeynum=1,flag,flag1,flag2,adder,q;

uintk,count,th,tl;

ucharth1=8;

ucharth2=5;

ucharth3=2;

ucharth4=0;

uchartab,w;

voiddelay(ucharz)

{

ucharx,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

ucharkey4()

{

if(K4==0)

{

delay(5);

if(K4==0)

{

while(!

K4);

keynum++;

if(keynum==5)keynum=1;

}

}

returnkeynum;

}

voidkey_lcd()

{

if(flag1==1&&k==3)

{

if(K3==0)

{

delay(5);

if(K3==0)

{

while(!

K3);

flag++;

if(flag==5)flag=1;

}

}

switch(flag)

{

case1:

{

if(K1==0)

{

delay(5);

if(K1==0)

{

th1++;

while(!

K1);

if(th1==10)th1=0;

}

}

if(K2==0)

{

delay(5);

if(K2==0)

{

th1--;

while(!

K2);

if(th1==-1)th1=9;

}

}

write_cmd(0xc3);

write_dat(th1+0x30);

}break;

case2:

{

if(K1==0)

{

delay(5);

if(K1==0)

{

th2++;

while(!

K1);

if(th2==10)th2=0;

}

}

if(K2==0)

{

delay(5);

if(K2==0)

{

th2--;

while(!

K2);

if(th2==-1)th2=9;

}

}

write_cmd(0xc4);

write_dat(th2+0x30);

}break;

case3:

{

if(K1==0)

{

delay(5);

if(K1==0)

{

th3++;

while(!

K1);

if(th3==10)th3=0;

}

}

if(K2==0)

{

delay(5);

if(K2==0)

{

th3--;

while(!

K2);

if(th3==-1)th3=9;

}

}

write_cmd(0xcb);

write_dat(th3+0x30);

}break;

case4:

{

if(K1==0)

{

delay(5);

if(K1==0)

{

th4++;

while(!

K1);

if(th4==10)th4=0;

}

}

if(K2==0)

{

delay(5);

if(K2==0)

{

th4--;

while(!

K2);

if(th4==-1)th4=9;

}

}

write_cmd(0xcc);

write_dat(th4+0x30);

}break;

default:

break;

}

}

elseflag1=0;

th=th1*10+th2;//获取设置温度的高位

tl=th3*10+th4;//获取设置温度的低位

}

voidalarm_speaker()//报警系统与当前温度进行比较并处理

{

if(temp<(tl*10))

{

speaker=~speaker;

L1=0;

L2=1;

adder++;

tab=temp/10;

write_add(adder,tab);

}

elseif(temp>(th*10))

{

speaker=~speaker;

L1=1;

L2=0;

adder++;

tab=temp/10;

write_add(adder,tab);

}

elseif(temp<(th*10)&&temp>(tl*10))

{

speaker=1;

L1=1;

L2=1;

}

}

voidmain()

{

systemtimerealtime;

led=0;

init_18b20();

init_lcd();

init_2402();

speaker=1;

while

(1)

{

k=key4();

get_ds1302(&realtime);//取时间

temp=read_temp();//取温度

delay(200);

//延时保持数据稳定避免数据刷新

switch(k)

{

case1:

//菜单一,显示时间

{

led=0;

write_cmd(0x80);

print("Time:

");

print(realtime.TimeString);

write_cmd(0xc0);

print("Date:

");

print(realtime.DateString);

}break;

case2:

//菜单二,显示温度

{

write_cmd(0x80);

print("DS18B20isOK");

write_cmd(0xc0);

print("NOWTEMP:

.C");

if(flagt==1)datadis[0]=0x2d;

elsedatadis[0]=temp/1000+0x30;

datadis[1]=temp/100%10+0x30;

datadis[2]=temp/10%10+0x30;

datadis[3]=0x2e;

datadis[4]=temp%10+0x30;

write_cmd(0xca);

print(datadis);

}break;

case3:

//菜单三,显示温度设置值

{

write_cmd(0x80);

print("changetemp:

");

write_cmd(0xc0);

print("TH=TL=");

write_cmd(0xc3);

write_dat(th1+0x30);

write_cmd(0xc4);

write_dat(th2+0x30);

write_cmd(0xc5);

write_dat(0xdf);//摄氏度远点

write_cmd(0xc6);

write_dat(0x43);

write_cmd(0xcb);

write_dat(th3+0x30);

write_cmd(0xcc);

write_dat(th4+0x30);

write_cmd(0xcd);//摄氏度符号

write_dat(0xdf);

write_cmd(0xce);

write_dat(0x43);

flag1=1;

}break;

case4:

//菜单四,记录报警温度

{

write_cmd(0x80);

print("ALARMTEMP");

write_cmd(0xc0);

print("RECORD:

");

write_cmd(0xcb);

write_dat(0xdf);

write_cmd(0xcc);

write_dat(0x43);

flag2=1;

}break;

default:

break;

}

key_lcd();//菜单三中温度设置的按键扫描

alarm_speaker();//报警系统通过2402存储超出的温度,并记录

if(K5==0)//按下K5,就显示当前报警的温度

{

delay(5);

if(K5==0)

{

while(!

K5);

q=read_add(adder);

}

};

if(flag2==1&&k==4)

{

write_cmd(0xc9);

write_dat(q/10%10+0x30);

write_cmd(0xca);

write_dat(q%10+0x30);

led=1;

}

}

}

#ifndef_lcd1602_h_

#define_lcd1602_h_

#include

#defineucharunsignedchar

#defineuintunsignedint

#defineLCD_IOP0

sbitLCD_RS=P2^4;

sbitLCD_RW=P2^5;

sbitLCD_EN=P2^6;

voiddelay11(uintz)

{

uintx,y;

for(x=z;x>0;x--)for(y=10;y>0;y--);

}

/*测忙信号

bitlcd_busy()

{

return(bit)(lcdrc&0x80);

}

/*写数据*/

voidwrite_cmd(ucharcmd)

{

LCD_RW=0;LCD_RS=0;LCD_EN=0;//LCD_RS和R/W同时为低电平时,可以写入指令.

LCD_IO=cmd;delay11(5);//下面用EN输入一个高脉冲.

LCD_EN=1;delay11(5);LCD_EN=0;

}

/*写命令*/

voidwrite_dat(uchardat)

{

LCD_RS=1;LCD_EN=0;LCD_RW=0;//LCD_RS为高,LCD_RW为低时,可以写入数据.

LCD_IO=dat;delay11(5);//下面用EN输入一个高脉冲.

LCD_EN=1;delay11(5);LCD_EN=0;

}

/*LCD初始化*/

voidinit_lcd()

{

LCD_EN=0;

write_cmd(0x38);

write_cmd(0x0c);

write_cmd(0x06);

write_cmd(0x01);

write_cmd(0x80);

}

voidprint(uchar*str)

{

while(*str!

='\0')

{

write_dat(*str);

str++;

}

}

#endif

#ifndef_ds18b20_h_

#define_ds18b20_h_

#defineucharunsignedchar

#defineuintunsignedint

//晶振22MHZ

//延时//

sbitDQ=P1^3;

bitflagt;

voiddelay_18b20(uinti)

{

while(i--);

}

/*****初始化程序****/

voidinit_18b20()

{

ucharx=0;

DQ=1;

delay_18b20(8);

DQ=0;

delay_18b20(80);

DQ=1;

delay_18b20(15);

x=DQ;

delay_18b20(15);

}

/**读一个字节**/

ucharread_byte()

{

uchari=0;

uchardat=0;

for(i=0;i<8;i++)

{

DQ=0;

dat>>=1;

DQ=1;

if(DQ)dat|=0x80;

delay_18b20(5);

}

returndat;

}

/**写一个字节**/

voidwrite_byte(uchardat)

{

uchari=0;

for(i=0;i<8;i++)

{

DQ=0;

DQ=dat&0x01;

delay_18b20(5);

DQ=1;

dat>>=1;

}

}

/**温度转换并读取温度**/

uintread_temp()

{

uchara=0;

ucharb=0;

uintt;

init_18b20();

write_byte(0xcc);//跳过读序号列号的操作

write_byte(0x44);//启动温度转换

delay_18b20(100);

init_18b20();

write_byte(0xcc);//跳过读序号列号的操作

write_byte(0xbe);//读取温度寄存器等(共可读9个寄存器)前两个就是温度

a=read_byte();//读第八位

b=read_byte();//读高八位

if(b&0x80)//高八位的最高位于是否为1,若为1,则为负温度,若为0,则是0-128;

{

flagt=1;

a=~a;

b=~b;

}

elseflagt=0;

t=(b*256+a)*5;//也可以写成t=(b*256+a)*0.625;returnt;

return(t>>3);//右移三位相当于5/8=0.625返回温度有4位,千、百、十、个,转化后有一位小数位,没有千位

}

#endif

#ifndef_2402_h_

#define_2402_h_

#defineucharunsignedchar

#defineuintunsignedint

sbitsda=P1^2;

sbitscl=P1^1;

//sbitsda=P1^6;

//sbitscl=P1^5;

voidnop()

{;;}

voidstart()//功能:

启动I2C总线,即发送I2C起始条件。

{

sda=1;

nop();

scl=1;

nop();

sda=0;

nop();

}

voidstop()//功能:

结束I2C总线,即发送I2C结束条件。

{

sda=0;

nop();

scl=1;

nop();

sda=1;

nop();

}

voidrespons()//功能:

主控器进行应答信号,(可以是应答或非应答信号)

{

uchari;

scl=1;

nop();

while((sda==1)&&(i<250))i++;

scl=0;

nop();

}

voidwrite_byte_2402(uchardat)//功能:

将数据dat发送出去,可以是地址,也可以是数据,发完后等待应答

{

uchari,temp;

temp=dat;

scl=0;

nop();

for(i=0;i<8;i++)

{

temp=temp<<1;

scl=0;/*置时钟线为低,准备接收数据位*/

nop();

sda=CY;

nop();

scl=1;/*置时钟线为高,通知被控器开始接收数据位*/

nop();

}

scl=0;

nop();

sda=1;//SDA数据线空闲

nop();

}

ucharread_byte_2402()//功能:

用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数

{

uchari,k;

scl=0;/*置时钟线为低,准备接收数据位*/

nop();

for(i=0;i<8;i++)

{

scl=1;/*置时钟线为高使数据线上数据有效,保持数据的稳定*/

nop();

k=(k<<1)|sda;

scl=0;

nop();

}

returnk;

}

voidwrite_add(ucharadd,uchardat)

{

start();

write_byte_2402(0xa0);

respons();

write_byte_2402(add);

respons();

write_byte_2402(dat);

respons();

stop();

}

ucharread_add(ucharadd)

{

uchark;

start();

write_byte_2402(0xa0);

respons();

write_byte_2402(add);

respons();

start();

write_byte_2402(0xa1);

respons();

k=read_byte_2402();

stop();

returnk;

}

voidinit_2402()

{

uinti;

sda=1;

nop();

scl=1;

nop();

for(i=0;i<256;i++)

{write_add(i,0);}

}

#endif

/****************************

DS1302内部函数

*****************************/

#ifndef_ds1302_h_

#define_ds1302_h_

sbitT_RST=P3^5;

sbitT_CLK=P3^6;

sbitT_IO=P3^4;

sbitACC0=ACC^0;

sbitACC7=ACC^7;

typedefstructsystemtime

{

ucharsecond;

ucharminute;

ucharhour;

ucharweek;

ucharday;

ucharmonth;

ucharyear;

ucharDateString[9];

ucharTimeString[9];

}systemtime;//定义的时间类型

/*向DS1302中写入1BYTE数据*/

voidwriteB(ucharucda)

{

uchari;

ACC=ucda;

for(i=8;i>0;i--)

{

T_IO=ACC0;

T_CLK=1;

T_CLK=0;

ACC=ACC>>1;

}

//T_IO=0;

}

/*从DS1302中读出1BYTE数据*/

ucharreadB()

{

uchari;

for(i=8;i>0;i--)

{

ACC=ACC>>1;

ACC7=T_IO;

T_CLK=1;

T_CLK=0;

}

return(ACC);

}

/*单字节读,向DS1302某地址中读出数据,

先写地址后写命令/数据*************/

ucharr_ds1302(ucharucaddr)

{

ucharucda;

T_RST=0;

T_CLK=0;

T_RST=1;

writeB(ucaddr);

ucda=readB();

T_CLK=1;

T_RST=0;

return(ucda);

}

/**********************************

读取DS1302当前时间,

格式为:

秒,分,时,日,月,星期,年

**********************************/

voidget_ds1302(systemtime*Time)

{

ucharreadtime;

readtime=r_ds1302(0x81);//秒寄存器读操作0x81

Time->second=((readtime&0x70)>>4)*10+(readtime&0x0f);//十位+个位

readtime=r_ds1302(0x83);//分寄存器读操作0x83

Time->minute=((readtime&0x70)>>4)*10+(readtime&0x0f);

readtime=r_ds1302(0x85);

Time->hour=((readtime&0x70)>>4)*10+(readtime&0x0f);

readtime=r_ds1302(0x87);

Time->day=((readtime&0x7

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 其它

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1