?? 溫度 濕度程序.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 + -