⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 温度 湿度程序.c

📁 实现监控环境中的温度
💻 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 + -