📄 温度 湿度程序.c
字号:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
/*****P1口定义*****/
sbit DQ = P2^0; //定义DS18B20端口DQ
sbit kaiguan=P2^1; //各种报警总开关
sbit beep=P2^2; //蜂鸣器
sbit red=P2^3; //高温报警
sbit jidianqi=P2^4; //继电器
sbit yellow=P2^5; //低温报警
sbit wei1=P1^0; //数码管位选控制定义
sbit wei2=P1^1;
sbit wei3=P1^2;
sbit wei4=P1^3;
sbit jiance=P3^2; //未检测到DS18B20时指示灯闪烁,检测到DS18B20时指示灯一直亮
sbit DIN = P0^7; //小数点
bit key=0; //显示开关标记
uchar ressive,i,j,p,q;
uchar flag,shan,biaoji; //串口中断标志
uchar presence;
uchar value;
uchar m=0;
uchar count=0;
uchar tem0 , tem1; //湿度
uchar temp0 , temp1;
uint f=0,n,k=0,r;
uchar code LEDData[ ] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,
0xF8,0x80,0x90,0xff};
uchar data temp_data[4] = {0x00,0x00,0x00,0x00}; //温度
uchar data shidu_data[4] = {0x00,0x00,0x00,0x00}; //湿度
uchar data display[5] = {0x00,0x00,0x00,0x00,0x00};
uchar data display2s[5] = {0x00,0x00,0x00,0x00,0x00};
uchar data setter[4]={0x00,0x00,0x00,0x00};
uchar data biaozhi[4]={0x00,0x00,0x00,0x00};
uchar code ditab[16] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
/**********************************************************/
void Delay(uint num)//延时函数
{
while( --num );
}
/**********************************************************/
void delay1s(uint z)
{
uint x,y;
for(x=10;x>0;x--);
for(y=z;y>0;y--);
}
/**********************************************************/
void delaysm(uint z) //数码管的延时1ms函数
{
uint x,y;
for(x=10;x>0;x--)
for(y=z;y>0;y--);
}
/**********************************************************/
Init_DS18B20(void)//初始化ds1820
{
presence=0;
DQ = 1; //DQ复位
Delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
Delay(90); //精确延时 大于 480us
DQ = 1; //拉高总线
Delay(8);
presence = DQ; //如果=0则初始化成功 =1则初始化失败
Delay(100);
DQ = 1;
return(presence); //返回信号,0=presence,1= no presence
}
/**********************************************************/
ReadOneChar()//读一个字节
{
uchar i = 0;
uchar dat = 0;
for (i = 8; i > 0; i--)
{
DQ = 0; // 给脉冲信号
dat >>= 1;
DQ = 1; // 给脉冲信号
if(DQ)
dat |= 0x80;
Delay(4);
}
return (dat);
}
/**********************************************************/
WriteOneChar(uchar dat)//写一个字节
{
uchar i = 0;
for (i = 8; i > 0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delay(5);
DQ = 1;
dat>>=1;
}
}
/*********************************************************/
Read_Temperature(void)//读取温度
{
Init_DS18B20();
if(presence==1)
{shan=1;
beep=0;
biaoji=1;} //DS18B20不正常,蜂鸣器报警,灯闪烁
else
{beep=1;
jiance=0;
biaoji=0;
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Delay(100);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
temp_data[0] = ReadOneChar(); //温度低8位
temp_data[1] = ReadOneChar(); //温度高8位
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
//display[3]=display[4]/100; //百位
setter[0]=display[4];
}
}
/*********************************************************/
Disp_Temperature() //显示温度
{
uchar n=0;
//temp_data[0] =0X91;
//temp_data[1] =0X01;
display[4]=temp_data[0]&0x0f;
display[0]=ditab[display[4]]; //查表得小数位的值
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
//display[3]=display[4]/100; //百位
// setter[0]=display[4];
display[1]=display[4]%100;
display[2]=display[1]/10;
display[1]=display[1]%10;
if(!display[2]) //高位为0,不显示
{display[2]=0xff;}
P0 =LEDData[display[0]] ; //显示小数位
wei1=0;
delaysm(10);
wei1=1;
P0 =LEDData[display[1]]; //显示个位
DIN = 0;
wei2=0;
delaysm(10);
wei2=1;
DIN = 1;
P0 =LEDData[display[2]]; //显示十位
wei3=0;
delaysm(10);
wei3=1;
P0 =0xfe; //显示数据类型
wei4=0;
delaysm(10);
wei4=1;
P1 = 0xff; //关闭显示
}
/*********************************************************/
Ddisp()
{
shidu_data[0] &= 0x0F;
shidu_data[1] &= 0x0F;
display2s[1]=shidu_data[1];
display2s[2]=shidu_data[0];
if(!display2s[2]) //高位为0,不显示
{display2s[2]=0xff;}
P0 =0x89; //显示H
wei1=0;
delaysm(10);
wei1=1;
P0 =LEDData[display2s[1]]; //显示个位
wei2=0;
delaysm(10);
wei2=1;
P0 =LEDData[display2s[2]]; //显示十位
wei3=0;
delaysm(10);
wei3=1;
P0 =0xbf; //湿度数据类型
wei4=0;
delaysm(10);
wei4=1;
P1=0xff;
}
/**************************************/
void timer0() interrupt 1
{
biaoji=0;
TR0=0;
TR1=0;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
//重装值 定时50000us OX4BFFH
tem0 = TL1; //读数
tem1 = TH1;
TL1=0x00; //定时器1清零
TH1=0x00;
TR0=1;
TR1=1;
biaoji=1;
//作标注位
}
/****************************************************************************
* 名称: timer1()
* 功能: 计数器,用于计数将555输出的频率,以计数相对湿度。
* 入口参数:
****************************************************************************/
void timer1() interrupt 3 //T1中断,表示计数的频率溢出,超出了可测量的频率范围
{
EA =0;
TR0=0;
TR1=0;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //重装值 定时50000us
TL1=0x00; //定时器1清零
TH1=0x00;
TR0=1;
TR1=1;
EA=1;
}
void Init_timer()
{
TMOD=0x51; //0101 0001 定时器0在模式1下工作16位定时器,定时方式 定时器1在模式1下工作16位计数器,T1负跳变加1
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //定时器0初值 定时50000us
TL1=0x00; //定时器1清零
TH1=0x00;
ET0=1; //使能定时器0中断
ET1=1; //使能定时器1中断
EA=1; //使能总中断
TR0=1; //开始计时
TR1=1;
}
void tran()
{
f = tem1;
f = ( f<<8 ) | tem0;
f = f * 20;
//这里f的值是最终读到的频率,不同频率对于不同相对湿度。
if(( 4000<= f)&&( f<=5244) )//相对湿度在有效范围内(0%--100%)
{//ceshi1s=0;//temp0 =7;temp1 =2;
if(( 5100<f)&&( f<= 5244) )
{ temp0 = 0; temp1 =(5244 -f)*10/142; }
if( (4960<f)&&( f<= 5100) )
{ temp0 = 1; temp1 =(5100 -f)*10/140; }
if( (4820<f)&&( f<= 4960 ) )
{ temp0 = 2; temp1 =(4960 -f)*10/140; }
if( (4680<f)&&( f<= 4820 ) )
{ temp0 = 3; temp1 =(4820 -f)*10/140; }
if( (4540<f)&&( f<= 4680 ) )
{ temp0 = 4; temp1 =(4680 -f)*10/140; }
if( (4400<f)&&( f<= 4540) )
{ temp0 = 5; temp1 =(4540 -f)*10/140; }
if( (4260<f)&&( f<= 4400 ) )
{ temp0 = 6; temp1 =(4400 -f)*10/140; }
if( (4120<f)&&( f<= 4260 ) )
{ temp0 = 7;temp1 =(4260 -f)*10/140; }
if( (4000<f)&&( f<= 4120 ))
{ temp0 = 8; temp1 =(4120 -f)*10/140; }
if( (3860<f)&&(f<= 4000))
{ temp0 = 9; temp1 =(4000 -f)*10/140; }
}
else
{
temp0 = 0; temp1 = 0;
}
r--;
if(r==0)
{ r=20;
shidu_data[0]=temp0;
shidu_data[1]=temp1;
shidu_data[0] &= 0x0F;
shidu_data[1] &= 0x0F;
shidu_data[3]= shidu_data[0] <<4;
shidu_data[2]=shidu_data[3] | shidu_data[1];
setter[1]=shidu_data[2];
}
}
/*********************************************************/
/**************************************************/
void main()
{
flag=0;
jiance=1;
ES=0;
SCON=0X50; //串口方式控制
T2CON=0X34;
RCAP2H=0XFF;
RCAP2L=0XDB;
EA=1;
ES=1;
i=20;
n=4;
p=200;
q=1;
j=30;
r=20;
Init_timer();
while(1)
{
if(biaoji)
{
biaoji=0;
ES=0;TR0=0;TR1=0;
tran();
ES=1;
TR0=1;TR1=1;
// shaomiao();
}
Read_Temperature();
if(q)
{P1=0xff;Disp_Temperature();}
else{P1=0xff;Ddisp();}
p--; //数码管交替显示
if(p==0)
{ p=200;
q=!q;
}
if(shan) //未检测到DS18B20时指示灯闪烁
{j--;
if(j==0)
{jiance=!jiance;j=30;}
}
i--; //C51发送数据
if(i==0)
{
i=20;
n--;
TR0=0;TR1=0;
if(n==3)
{SBUF=0xaa; //发送数据开始标志
while(!TI);
TI=0;}
if(n==2)
{SBUF=setter[0]; //温度数据(16进制)
while(!TI);
TI=0;}
if(n==1)
{SBUF=setter[1]; //湿度数据(10进制)
while(!TI);
TI=0;}
if(n==0)
{SBUF=0xbb; //发送数据结束标志
while(!TI);
TI=0;n=4;}
TR0=1;TR1=1;
}
/////************/////////////
//C51串口接收数据处理
/////////******/////////////////////
if(flag==1)
{ ES=0;
flag=0;
delay1s(20);
if(ressive==0x22) //高温报警
{red=0;}
if(ressive==0x55) //继电器动作
{jidianqi=0;}
if(ressive==0x11) //低温报警
{yellow=0;}
if(ressive==0x99||kaiguan==0) //结束各种报警
{red=1;yellow=1;jidianqi=1;}
ES=1;
}
// delay1s(100);
// P1=0xff;
}
}
/*********************************************************/
void ser0() interrupt 4
{
RI=0;
ressive=SBUF;
flag=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -