#include <reg52.h>
#include <intrins.h>
#include <math.h>
#ifndef __DELAY_H__
#define __DELAY_H__
#ifndef __DHT11_H__
#define __DHT11_H__
#ifndef __LCD1602_H__
#define __LCD1602_H__
#define uchar unsigned char
#define uint unsigned int
#define LCD_PINDATA P0 //數據端口定義
sbit CS = P1^2;
sbit Clk = P1^1;
sbit DATI = P1^0;
sbit DATO = P1^0; //ADC0832串口
sbit RS = P1^4; //RS
sbit RW = P1^5; //RW
sbit E = P1^6;
sbit vled = P1^7;
sbit DHT11_DQ1 = P3^7; //DHT11數據傳輸口
sbit DHT11_DQ2 = P3^7; //DHT11數據傳輸口
sbit BUZZER = P1^3; //蜂鳴器驅動端口==P1^3
sbit Reduc = P3^2; //按鍵鍵輸入端口==P3^2
sbit Add = P3^3; //按鍵加輸入端口==P3^3
sbit Mode = P3^4; //按鍵加輸入端口==P3^4
uchar Rx_buf[4],Rxnum=0;
uchar T1L=15,T1H=35,R1L=30,R1H=80;
uchar U8count,U8temp,U8FLAG,U8comdata;
extern void _nop_ (void);
void InitUART(void) //串口的基本配置,配置他的波特率是9600
{
TMOD = 0x20;
SCON = 0x50;
TH1 = 0xFD;
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}
//------UART 發送一字節------//
void UART_send_byte(char dat)
{
SBUF = dat;
while (TI == 0);
TI = 0;
}
//------UART 發送字符串------//
void UART_send_string(unsigned char *buf)
{
while (*buf != '\0')
{
UART_send_byte(*buf++);
}
}
void Delay1us(uint t)
{
while(t--)_nop_();
}
void Delay(uint T)
{
uchar i;
for(T;T>0;T--)
for(i=200;i>0;i--);
}
//--#endif--//
//------DHT11模塊------//
void Delay_10us(void)
{
uchar i;
i--;
i--;
i--;
i--;
i--;
i--;
}
void COM(uchar n)
{
uchar i;
for(i=0;i<8;i++)
{
U8FLAG=2;
if(n){while((!DHT11_DQ1)&&U8FLAG++);}
else {while((!DHT11_DQ2)&&U8FLAG++);}
Delay_10us();
Delay_10us();
U8temp=0;
if(n){if(DHT11_DQ1)U8temp=1;}
else {if(DHT11_DQ2)U8temp=1;}
U8FLAG=2;
if(n){while((DHT11_DQ1)&&U8FLAG++);}
else {while((DHT11_DQ2)&&U8FLAG++);}
if(U8FLAG==1)break;
U8comdata<<=1;
U8comdata|=U8temp;
}
}
uchar Read_TRH(uchar ch,uchar n)
{
uchar TRH_data=0;
static uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
static uchar U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
if(n)DHT11_DQ1=0;
else DHT11_DQ2=0;
Delay(24);
if(n)DHT11_DQ1=1;
else DHT11_DQ2=1;
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
if(n)DHT11_DQ1=1;
else DHT11_DQ2=1;
if(!DHT11_DQ1 || !DHT11_DQ2)
{
U8FLAG=2;
if(n){while((!DHT11_DQ1)&&U8FLAG++);}
else {while((!DHT11_DQ2)&&U8FLAG++);}
U8FLAG=2;
if(n){while((DHT11_DQ1)&&U8FLAG++);}
else {while((DHT11_DQ2)&&U8FLAG++);}
COM(n);U8RH_data_H_temp=U8comdata;
COM(n);U8RH_data_L_temp=U8comdata;
COM(n);U8T_data_H_temp=U8comdata;
COM(n);U8T_data_L_temp=U8comdata;
COM(n);U8checkdata_temp=U8comdata;
if(n)DHT11_DQ1=1;
else DHT11_DQ2=1;
U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
if(U8temp==U8checkdata_temp)
{
U8RH_data_H=U8RH_data_H_temp;
U8RH_data_L=U8RH_data_L_temp;
U8T_data_H=U8T_data_H_temp;
U8T_data_L=U8T_data_L_temp;
U8checkdata=U8checkdata_temp;
}
}
if(ch)TRH_data=U8RH_data_H;
else TRH_data=U8T_data_H;
return TRH_data;
}
//---#endif---//
//------ADC0832轉換模塊------//
unsigned char adc0832(unsigned char CH)
{
unsigned char dat = 0x00; //AD值
unsigned char i,test,adval;
adval = 0x00;
test = 0x00;
Clk = 0; //初始化
DATI = 1;
_nop_();
CS = 0;
_nop_();
Clk = 1;
_nop_();
if ( CH == 0x00 ) //通道選擇
{
Clk = 0;
DATI = 1; //通道0的第一位
_nop_();
Clk = 1;
_nop_();
Clk = 0;
DATI = 0; //通道0的第二位
_nop_();
Clk = 1;
_nop_();
}
else
{
Clk = 0;
DATI = 1; //通道1的第一位
_nop_();
Clk = 1;
_nop_();
Clk = 0;
DATI = 1; //通道1的第二位
_nop_();
Clk = 1;
_nop_();
}
Clk = 0;
DATI = 1;
for( i = 0;i < 8;i++ ) //讀取前8位的值
{
_nop_();
adval <<= 1;
Clk = 1;
_nop_();
Clk = 0;
if (DATO)
adval |= 0x01;
else
adval |= 0x00;
}
for (i = 0; i < 8; i++) //讀取后8位的值
{
test >>= 1;
if (DATO)
test |= 0x80;
else
test |= 0x00;
_nop_();
Clk = 1;
_nop_();
Clk = 0;
}
if (adval == test) //比較前8位與后8位的值,如果不相同舍去。若一直出現顯示為零,請將該行去掉
dat = test;
_nop_();
CS = 1; //釋放ADC0832
DATO = 1;
Clk = 1;
return dat;
}
uint read_data(uchar N)
{
uint val=0;
vled=0;
Delay1us(20);
val=adc0832(N);
vled=1;
Delay1us(400);
return val;
}
//------lcd1602------//
void WriteCOMDATA(uchar LCD_DATA,uchar N)
{
Delay(5);
E=1;
RW=0;
RS=N;
LCD_PINDATA=LCD_DATA;
E=0;
}
void LCD_Init(void)
{
WriteCOMDATA(0x01,0);
Delay(500);
WriteCOMDATA(0x38,0);
Delay(10);
WriteCOMDATA(0x06,0);
Delay(10);
WriteCOMDATA(0x0C,0);
Delay(10);
}
void WriteChar(uchar Row,uchar Col,uchar Num,uchar *pBuffer)
{
uchar i;
if(Row==1)Row=0x80+Col;
else Row=0xC0+Col;
WriteCOMDATA(Row,0);
for(i=Num;i!=0;i--)
{
WriteCOMDATA(*pBuffer,1);
pBuffer++;
}
}
//----#endif------//
void main(void)
{
double PM,pm1,pm2;
int PMVAL=0,HPM=200,PM_count=0,pm1_count=0;
uchar T1_data=0,R1_data=0,T2_data=0,R2_data=0;//溫度、濕度變量
uchar shezhi_flag=1,Mode_flag=1,n=1;//設置變量
uchar bueezr_flag=0,count=0,buzzer_time=9;//蜂鳴器報警變量
uint Mode_count=0;
uchar disp[16] ={"PM2.5:0000ug/m3 "};
uchar disp1[16]= {"T :00C RH:00%"};
uchar Tx_Buf[15];
InitUART(); //初始化串口
LCD_Init();
WriteChar(1,0,16,disp); //在第一行顯示‘內容’
WriteChar(2,0,16,disp1); //在第二行顯示‘內容’
while(1)
{
T1_data=Read_TRH(0,0);//溫度
disp1[3]=T1_data/10+0x30;//十位
disp1[4]=T1_data%10+0x30;//個位
R1_data=Read_TRH(1,0);//濕度
disp1[13]=R1_data/10+0x30;//十位
disp1[14]=R1_data%10+0x30;//個位
pm1+=read_data(1);
if(++PM_count>=20)
{
PM_count=0;
pm1=pm1/20;
pm2+=pm1;
pm1=0;
if(++pm1_count>=5)
{
pm1_count=0;
PM=pm2/5;
PM=PM*50/255;
PM-=4;
PM/=5;
PM*=1000;
PMVAL=PM;
PMVAL+=235; PMVAL=PMVAL/9;
if(PMVAL>=9999)PMVAL=9999;
WriteCOMDATA(0x86,0);
if(PMVAL<0)//PMVAL=0;
{WriteCOMDATA(0+0x30,1);PMVAL=abs(PMVAL);}
else WriteCOMDATA(PMVAL/1000+0x30,1);
WriteCOMDATA(PMVAL/100%10+0x30,1);
WriteCOMDATA(PMVAL/10%10+0x30,1);
WriteCOMDATA(PMVAL%10+0x30,1);
PM=pm1=pm2=0;
}
}
/*調用報警函數,溫濕度是否在設定范圍內*/
//溫度值與報警值比較
if(T1_data<T1L)
{
bueezr_flag=1;//報警標志位置1
}
else if(T1_data>T1H)
{
bueezr_flag=1;//報警標志位置1
}
//濕度值與報警值比較
if(R1_data<R1L)
{
bueezr_flag=1;//報警標志位置1
}
else if(R1_data>R1H)
{
bueezr_flag=1;//報警標志位置1
}
//PM值與報警值比較
if(PMVAL>HPM)
{
bueezr_flag=1;
}
if(T1_data>T1L&&T1_data<T1H && R1_data>R1L&&R1_data<R1H && PMVAL<HPM)
{
bueezr_flag=0;
BUZZER=1;
}
/*******蜂鳴器報警********/
count++;if(count>buzzer_time*10)count=buzzer_time+1;
if(count%buzzer_time==0 && bueezr_flag)
{
BUZZER=~BUZZER;//蜂鳴器取反 發出聲音提示
}
/*******Mode鍵設置報警參數********/
if(Mode==0 && Mode_flag)
{
WriteCOMDATA(0x0F,0);//LCD顯示光標
Delay(100);
if(Mode==0)
{
BUZZER=1;
bueezr_flag=0;
Mode_flag=0;
shezhi_flag=1;
n=1;
while(1)
{
switch(shezhi_flag)
{
case 1:
if(n)
{
n=0;
WriteChar(1,0,16,"T1L:00C T1H:00C");//在第一行顯示內容
WriteChar(2,0,16,"R1L:00% R1H:00%");//在第二行顯示內容
WriteCOMDATA(0x8D,0);WriteCOMDATA(T1H/10+0x30,1);
WriteCOMDATA(0x8E,0);WriteCOMDATA(T1H%10+0x30,1);
WriteCOMDATA(0xC4,0);WriteCOMDATA(R1L/10+0x30,1);
WriteCOMDATA(0xC5,0);WriteCOMDATA(R1L%10+0x30,1);
WriteCOMDATA(0xCD,0);WriteCOMDATA(R1H/10+0x30,1);
WriteCOMDATA(0xCE,0);WriteCOMDATA(R1H%10+0x30,1);
}
WriteCOMDATA(0x84,0);WriteCOMDATA(T1L/10+0x30,1);
WriteCOMDATA(0x85,0);WriteCOMDATA(T1L%10+0x30,1);
WriteCOMDATA(0x85,0);
break;
case 2:
WriteCOMDATA(0x8D,0);WriteCOMDATA(T1H/10+0x30,1);
WriteCOMDATA(0x8E,0);WriteCOMDATA(T1H%10+0x30,1);
WriteCOMDATA(0x8E,0);
break;
case 3:
WriteCOMDATA(0xC4,0);WriteCOMDATA(R1L/10+0x30,1);
WriteCOMDATA(0xC5,0);WriteCOMDATA(R1L%10+0x30,1);
WriteCOMDATA(0xC5,0);
break;
case 4:
WriteCOMDATA(0xCD,0);WriteCOMDATA(R1H/10+0x30,1);
WriteCOMDATA(0xCE,0);WriteCOMDATA(R1H%10+0x30,1);
WriteCOMDATA(0xCE,0);
break;
case 5:
if(n)
{
n=0;
WriteChar(1,0,16," PM2.5 SET ");//在第一行顯示內容
WriteChar(2,0,16,"HPM2.5: ug/m3");//在第二行顯示內容
}
WriteCOMDATA(0xC7,0);
WriteCOMDATA(HPM/1000+0x30,1);
WriteCOMDATA(HPM/100%10+0x30,1);
WriteCOMDATA(HPM/10%10+0x30,1);
WriteCOMDATA(HPM%10+0x30,1);
WriteCOMDATA(0xCA,0);
break;
}
Delay(200);
//加
if(Reduc==0)
{
Delay(200);
//while(Reduc==0);
switch(shezhi_flag)
{
case 1:T1L+=1;break;
case 2:T1H+=1;break;
case 3:R1L+=1;break;
case 4:R1H+=1;break;
case 5:HPM+=1;break;
}
}
//減
if(Add==0)
{
Delay(200);
//while(Add==0);
switch(shezhi_flag)
{
case 1:T1L-=1;break;
case 2:T1H-=1;break;
case 3:R1L-=1;break;
case 4:R1H-=1;break;
case 5:HPM-=1;break;
}
}
//短按切換設置項目 長按退出設置頁面
if(Mode==0)
{
Delay(300);
while(Mode==0)
{
Delay(300);
Mode_count++;
if(Mode_count>6)
{
WriteChar(1,0,16,"PM2.5:0000ug/m3 ");//在第一行顯示內容
WriteCOMDATA(0x86,0);
if(PMVAL<0)//PMVAL=0;
{WriteCOMDATA(0+0x30,1);PMVAL=abs(PMVAL);}
else WriteCOMDATA(PMVAL/1000+0x30,1);
WriteCOMDATA(PMVAL/100%10+0x30,1);
WriteCOMDATA(PMVAL/10%10+0x30,1);
WriteCOMDATA(PMVAL%10+0x30,1);
WriteChar(2,0,16,disp1); //在第二行顯示內容
}
}
if(Mode_count>6)
{
Mode_count=0;shezhi_flag=0;
//當下限值大于上限值時,蜂鳴器鳴叫1S提示,參數設置有誤
if(T1L>T1H || R1L>R1H)
{
BUZZER=0;Delay(1000);BUZZER=1;
}
//否則退出設置頁面,返回主頁面
else
{
WriteCOMDATA(0x0C,0);//關閉LCD光標
Delay(10);
n=0;
break;
}
}
else Mode_count=0;
shezhi_flag++;
if(shezhi_flag>5)shezhi_flag=1;
if(shezhi_flag==1 || shezhi_flag==5)n=1;
pm1+=read_data(1);
if(++PM_count>=20)
{
PM_count=0;
pm1=pm1/20;
pm2+=pm1;
pm1=0;
if(++pm1_count>=15)
{
pm1_count=0;
PM=pm2/15;
PM=PM*50/255;
PM-=4;
PM/=5;
PM*=1000;
PMVAL=PM;
PMVAL-=480; PMVAL=PMVAL/3;
if(PMVAL>=9999)PMVAL=9999;
PM=pm1=pm2=0;
}
}
}
}
}
}
}
} |