標(biāo)題:
修改好的單片機(jī)PM2.5+DHT11溫濕度傳感程序
[打印本頁]
作者:
canyi
時(shí)間:
2021-5-14 15:09
標(biāo)題:
修改好的單片機(jī)PM2.5+DHT11溫濕度傳感程序
#include <reg52.h> //頭文件
#include "1602.h"
#include "DHT11.h"
#include <adc0832.h>
#include <intrins.h>
#include "eeprom52.h"
#define uchar unsigned char //定義字符類型
#define uint unsigned int
typedef bit BOOL ;
sbit DQ=P1^5; //DTH11
sbit beep = P1^7; //蜂鳴器
sbit LED = P1^6; //粉塵傳感器內(nèi)部LED控制
uchar FlagStart = 0; //標(biāo)志位
uint Counter;
uint DUST_SET; //固體顆粒的閾值
uchar ADC_Get[10]={0}; //定義AD采樣數(shù)組
uchar num=0; //定義的變量,采集一段時(shí)間內(nèi)的值
uchar time1=0; //定義的時(shí)間變量,用于溫濕度處理顯示
uchar time2=0; //定義的時(shí)間變量,開機(jī)報(bào)警功能等待溫度濕度PM2.5數(shù)據(jù)處理完成再啟動(dòng),避免蜂鳴器開機(jī)就亂叫。
uint DUST; //定義的PM2.5的值
uint DUST_Value; //定義的PM2.5的值
uchar GetADVal(uchar);
uchar RH,TH;
uint num1,num2,Temp_H,Temp_L,Humi_H,Humi_L,s_dengji; //定義的報(bào)警值,參數(shù)具有斷電保存功能,僅支持STC單片機(jī)
uchar yemian=0; //定義的頁面標(biāo)志
uchar flat=1; //定義的判斷標(biāo)志
sbit K1=P3^2; //按鍵定義
sbit K2=P3^3;
sbit K3=P3^4;
void Delay_10us(void)
{
uchar i;
i--;
i--;
i--;
i--;
i--;
}
/***********************1ms延時(shí)函數(shù)*****************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}
/******************把數(shù)據(jù)保存到單片機(jī)內(nèi)部eeprom中******************/
void write_eeprom()
{
num1=s_dengji/256; //因?yàn)閑eprom每個(gè)區(qū)間最大存放256個(gè)字節(jié),當(dāng)大于要分開存儲(chǔ)
num2=s_dengji%256;
SectorErase(0x2000);
byte_write(0x2001, num1);
byte_write(0x2002, num2);
byte_write(0x2003, Temp_H);
byte_write(0x2004, Temp_L);
byte_write(0x2005, Humi_H);
byte_write(0x2006, Humi_L);
byte_write(0x2060, a_a);
}
/******************把數(shù)據(jù)從單片機(jī)內(nèi)部eeprom中讀出來*****************/
void read_eeprom()
{
num1 = byte_read(0x2001);
num2 = byte_read(0x2002);
Temp_H = byte_read(0x2003);
Temp_L = byte_read(0x2004);
Humi_H = byte_read(0x2005);
Humi_L = byte_read(0x2006);
a_a = byte_read(0x2060);
s_dengji= num1*256+num2;
}
/**************開機(jī)自檢eeprom初始化*****************/
void init_eeprom()
{
read_eeprom(); //先讀
if(a_a != 2) //新的單片機(jī)初始單片機(jī)內(nèi)問eeprom
{
num1=200/256;
num2=200%256;
Temp_H = 35;
Temp_L = 5;
Humi_H = 80;
Humi_L = 10;
a_a = 2;
write_eeprom();
}
}
//**************************延時(shí)函數(shù)
void delay_ms2(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
//**************************初始化DTH11***********************/
bit Init_DTH11()
{
bit flag;
uchar num;
DQ=0;
delay_ms2(19); // >18ms
DQ=1;
for(num=0;num<10;num++); // 20-40us 34.7us
for(num=0;num<12;num++);
flag=DQ;
for(num=0;num<11;num++); //DTH響應(yīng)80us
for(num=0;num<24;num++); //DTH拉高80us
return flag;
}
//****************************讀DTH11數(shù)據(jù)
uchar DTH11_RD_CHAR()
{
uchar byte=0;
uchar num;
uchar num1;
while(DQ==1);
for(num1=0;num1<8;num1++)
{
while(DQ==0);
byte<<=1; //高位在前
for(num=0;DQ==1;num++);
if(num<10)
byte|=0x00;
else
byte|=0x01;
}
return byte;
}
//******************************讀取DTH11溫度和濕度
void DTH11_DUSHU()
{
uchar num;
if(Init_DTH11()==0)
{
RH=DTH11_RD_CHAR(); //
DTH11_RD_CHAR();
TH=DTH11_RD_CHAR();
DTH11_RD_CHAR();
DTH11_RD_CHAR();
for(num=0;num<17;num++); //最后BIT輸出后拉低總線50us
DQ=1;
}
}
///////////////////////////////////////////////////////////////////////////
//DS---185頁 定時(shí)器初始化 定時(shí)10ms
void Timer0_Init()
{
//AUXR=0x80; //Time work in 1T mode
TMOD= 0x01;
TL0 = (65536-30000)/256;
TH0 = (65536-30000)%256;
TR0 = 1;
ET0 = 1;
EX0 = 1; //開外部中斷0
IT0 = 0; //電平觸發(fā)
EA = 1;
}
//定時(shí)器0中斷
void Timer0_ISR (void) interrupt 1 using 0
{
uint i,j;
TL0 = (65536-30000)/256;
TH0 = (65536-30000)%256;
LED=0; //開啟傳感器的LED
for (j=0;j<30;j++); //0.28ms //延時(shí)0.28ms
ADC_Get[num]=Get_AD_Result(); //開啟ADC采集
num++;
if(num>10)
{
FlagStart=1;
num=0;
TR0 = 0; //先關(guān)閉定時(shí)器0
} //采集10次,關(guān)閉定時(shí)器0,進(jìn)行數(shù)據(jù)處理
//關(guān)閉傳感器LED
LED=1;
}
//中值濾波
//算法:先進(jìn)行排序,然后將數(shù)組的中間值作為當(dāng)前值返回。
uchar Error_Correct(uchar *str,uchar num)
{
unsigned char i=0;
unsigned char j=0;
uchar Temp=0;
//排序
for(i=0;i<num-1;i++)
{
for(j=i+1;j<num;j++)
{
if(str[i]<str[j])
{
Temp=str[i];
str[i]=str[j];
str[j]=Temp;
}
}
}
//去除誤差,取中間值
return str[num/2];
}
void wenshidu() //溫濕度處理函數(shù)
{
time1++;
if(time1>=5) //避免液晶快速刷新顯示
{
EA=0;
time1=0;
DTH11_DUSHU();
DTH11_DUSHU();
EA=1;
LCD_Show2(2,1,TH); //溫度實(shí)時(shí)顯示
LCD_Show2(11,1,RH); //濕度實(shí)時(shí)顯示
LCD_Show3(6,0,DUST); //PM2.5的值實(shí)時(shí)顯示
}
}
void voice() //按鍵提示音
{
beep = 0; //打開蜂鳴器
delay_1ms(30); //短暫延時(shí)
beep = 1; //關(guān)閉蜂鳴器
}
void Outside_Int1(void) interrupt 0 using 1 //打開外部中斷處理函數(shù) 優(yōu)點(diǎn),進(jìn)入設(shè)置界面可以快速響應(yīng),避免長時(shí)間等待
{
if(K1==0 && K2==1 && K3==1 )
{
delay_1ms(20);
if(K1==0 && K2==1 && K3==1)
{
while(K1==0 && K2==1 && K3==1)
;
num=11;
yemian++;
if(yemian>=6) { yemian=0; flat=1;}
voice(); //提示音
}
}
}
void key() //對里面的數(shù)值進(jìn)行修改
{
if(K1==0 && K2==1 && K3==1 )
{
delay_1ms(20);
if(K1==0 && K2==1 && K3==1)
{
while(K1==0 && K2==1 && K3==1)
;
TR0 = 0;
yemian++;
if(yemian>=6) { yemian=0; flat=1;}
voice(); //提示音
}
}
if(K1==1 && K2==0 && K3==0) //長按5秒,K2和K3按鍵,系統(tǒng)設(shè)置值恢復(fù)初始值
{
delay_1ms(20);
if(K1==1 && K2==0 && K3==0)
{
while(K1==1 && K2==0 && K3==0)
;
s_dengji = 200;
Temp_H = 35;
Temp_L = 5;
Humi_H = 80;
Humi_L = 10;
write_eeprom();
beep = 0;
delay_1ms(200);
beep = 1;
}
}
}
void shezhi() //獨(dú)立按鍵程序
{
if(!K2) //
{
delay_1ms(100);
if(!K2)
{
;
if(yemian==1)
{
if(s_dengji<999 ) { s_dengji++;} //加1
LCD_Show3(5,1,s_dengji);
}
if(yemian==2)
{
if(Temp_H<99 ) { Temp_H++;} //加1
LCD_Show2(7,1,Temp_H);
}
if(yemian==3)
{
if(Temp_L<99 ) { Temp_L ++;} //加1
LCD_Show2(7,1,Temp_L);
}
if(yemian==4)
{
if(Humi_H<99 ) { Humi_H ++;} //加1
LCD_Show2(7,1,Humi_H);
}
if(yemian==5)
{
if(Humi_L<99 ) { Humi_L ++;} //加1
LCD_Show2(7,1,Humi_L);
}
write_eeprom(); //保存數(shù)據(jù)
voice(); //提示音
}
}
if(!K3) //
{
delay_1ms(100);
if(!K3)
{
;
if(yemian==1)
{
if(s_dengji>1) { s_dengji--; } //濃度設(shè)置數(shù)減1
LCD_Show3(5,1,s_dengji);
}
if(yemian==2)
{
if(Temp_H>1) { Temp_H--; } //濃度設(shè)置數(shù)減1
LCD_Show2(7,1,Temp_H);
}
if(yemian==3)
{
if(Temp_L>1) { Temp_L--; } //濃度設(shè)置數(shù)減1
LCD_Show2(7,1,Temp_L);
}
if(yemian==4)
{
if(Humi_H>1) { Humi_H--; } //濃度設(shè)置數(shù)減1
LCD_Show2(7,1,Humi_H);
}
if(yemian==5)
{
if(Humi_L>1) { Humi_L--; } //濃度設(shè)置數(shù)減1
LCD_Show2(7,1,Humi_L);
}
write_eeprom(); //保存數(shù)據(jù)
voice(); //提示音
}
}
}
//****************報(bào)警函數(shù)*************
void baojing()
{
if(DUST >= s_dengji || TH>=Temp_H || TH<=Temp_L || RH>=Humi_H || RH<=Humi_L ) //報(bào)警
{
beep = ~beep; //蜂鳴器報(bào)警
}
else
{
beep = 1;
}
}
void chengxu() //主界面處理程序
{
if(FlagStart==1) //10次采集完成
{
DUST=Error_Correct(ADC_Get,10); //求取10次AD采樣的值
DUST_Value=(DUST/256.0)*5000-200; //
DUST_Value=DUST_Value*0.32;
if(DUST_Value<0) DUST_Value=0;
if(DUST_Value>999) DUST_Value=999; //限位
DUST=(uint)DUST_Value; //
time2++;
if(time2>5) //開機(jī)后程序運(yùn)行5次再啟動(dòng)蜂鳴器功能
//開機(jī)報(bào)警功能等待溫度濕度PM2.5數(shù)據(jù)處理完成再啟動(dòng),避免蜂鳴器開機(jī)就亂叫。
{
time2=6;
baojing();
}
wenshidu();
if(yemian==0)
{
Delay_10us();
TL0 = (65536-30000)/256;
TH0 = (65536-30000)%256;
TR0 = 1; //開啟定時(shí)器0
FlagStart=0;
}
}
}
void main()
{
init_eeprom();
LCD_Init(); //液晶初始化
LCD_Clear();//清屏
LCD_Write_String(4,0,"Welcome");
delay_ms(2000);
Timer0_Init(); //定時(shí)器0初始化
while(1)
{
key(); //獨(dú)立按鍵程序
//====================yemian==0時(shí) 進(jìn)入工作狀態(tài)=================================
if(yemian==0)
{
if(flat==1)
{
flat=2;
LCD_Clear();//清屏
LCD_Write_String(0,0,"PM2.5: ug/m3 ");
LCD_Write_String(0,1,"T: C H: %RH");
LCD_Write_Char(4,1,0xdf);
TL0 = (65536-30000)/256;
TH0 = (65536-30000)%256;
TR0 = 1; //開啟定時(shí)器0
EA = 1;
}
chengxu();//主界面處理程序
}
//====================yemian==1時(shí) ======PM2.5報(bào)警值========================
if(yemian==1)
{
if(flat==2)
{
flat=3;
beep = 1;
TR0 = 0; //
EA=0;
LCD_Clear();//清屏
LCD_Write_String(0,0," Set PM2.5 ");
LCD_Write_String(0,1," ug/m3 ");
}
shezhi() ;
LCD_Show3(5,1,s_dengji);
}
//====================yemian==2時(shí) 溫度上限==============================
if(yemian==2)
{
if(flat==3)
{
flat=4;
beep = 1;
TR0 = 0; //
EA=0;
LCD_Clear();//清屏
LCD_Write_String(0,0," Set Temp_H ");
LCD_Write_String(0,1," C ");
LCD_Write_Char(9,1,0xdf);
}
shezhi() ;
LCD_Show2(7,1,Temp_H);
}
//====================yemian==3時(shí) 溫度下限==============================
if(yemian==3)
{
if(flat==4)
{
flat=5;
beep = 1;
TR0 = 0; //
EA=0;
LCD_Clear();//清屏
LCD_Write_String(0,0," Set Temp_L ");
LCD_Write_String(0,1," C ");
LCD_Write_Char(9,1,0xdf);
}
shezhi() ;
LCD_Show2(7,1,Temp_L);
}
//====================yemian==4時(shí) 濕度上限==============================
if(yemian==4)
{
if(flat==5)
{
flat=6;
beep = 1;
TR0 = 0; //
EA=0;
LCD_Clear();//清屏
LCD_Write_String(0,0," Set Humi_H ");
LCD_Write_String(0,1," % ");
}
shezhi() ;
LCD_Show2(7,1,Humi_H);
}
//====================yemian==5時(shí) 濕度下限==============================
if(yemian==5)
{
if(flat==6)
{
flat=1;
beep = 1;
TR0 = 0; //
EA=0;
LCD_Clear();//清屏
LCD_Write_String(0,0," Set Humi_L ");
LCD_Write_String(0,1," % ");
}
shezhi() ;
LCD_Show2(7,1,Humi_L);
}
}
}
復(fù)制代碼
51hei.png
(9.44 KB, 下載次數(shù): 75)
下載附件
2021-5-14 15:28 上傳
以上代碼下載:
PM2.5+溫濕度程序.rar
(86.7 KB, 下載次數(shù): 45)
2021-5-14 15:08 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
a1s2d3f4555
時(shí)間:
2022-3-26 16:42
大佬有原理圖嗎?想看看
作者:
Brussino
時(shí)間:
2024-4-25 15:36
您好我想請問一下,我的溫濕度沒有問題,但是PM沒有顯示是為什么呢
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1