标题:
修改好的单片机PM2.5+DHT11温湿度传感程序
[打印本页]
作者:
canyi
时间:
2021-5-14 15:09
标题:
修改好的单片机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; //粉尘传感器内部LED控制
uchar FlagStart = 0; //标志位
uint Counter;
uint DUST_SET; //固体颗粒的阈值
uchar ADC_Get[10]={0}; //定义AD采样数组
uchar num=0; //定义的变量,采集一段时间内的值
uchar time1=0; //定义的时间变量,用于温湿度处理显示
uchar time2=0; //定义的时间变量,开机报警功能等待温度湿度PM2.5数据处理完成再启动,避免蜂鸣器开机就乱叫。
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; //定义的报警值,参数具有断电保存功能,仅支持STC单片机
uchar yemian=0; //定义的页面标志
uchar flat=1; //定义的判断标志
sbit K1=P3^2; //按键定义
sbit K2=P3^3;
sbit K3=P3^4;
void Delay_10us(void)
{
uchar i;
i--;
i--;
i--;
i--;
i--;
}
/***********************1ms延时函数*****************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}
/******************把数据保存到单片机内部eeprom中******************/
void write_eeprom()
{
num1=s_dengji/256; //因为eeprom每个区间最大存放256个字节,当大于要分开存储
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);
}
/******************把数据从单片机内部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;
}
/**************开机自检eeprom初始化*****************/
void init_eeprom()
{
read_eeprom(); //先读
if(a_a != 2) //新的单片机初始单片机内问eeprom
{
num1=200/256;
num2=200%256;
Temp_H = 35;
Temp_L = 5;
Humi_H = 80;
Humi_L = 10;
a_a = 2;
write_eeprom();
}
}
//**************************延时函数
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响应80us
for(num=0;num<24;num++); //DTH拉高80us
return flag;
}
//****************************读DTH11数据
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页 定时器初始化 定时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; //电平触发
EA = 1;
}
//定时器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 //延时0.28ms
ADC_Get[num]=Get_AD_Result(); //开启ADC采集
num++;
if(num>10)
{
FlagStart=1;
num=0;
TR0 = 0; //先关闭定时器0
} //采集10次,关闭定时器0,进行数据处理
//关闭传感器LED
LED=1;
}
//中值滤波
//算法:先进行排序,然后将数组的中间值作为当前值返回。
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() //温湿度处理函数
{
time1++;
if(time1>=5) //避免液晶快速刷新显示
{
EA=0;
time1=0;
DTH11_DUSHU();
DTH11_DUSHU();
EA=1;
LCD_Show2(2,1,TH); //温度实时显示
LCD_Show2(11,1,RH); //湿度实时显示
LCD_Show3(6,0,DUST); //PM2.5的值实时显示
}
}
void voice() //按键提示音
{
beep = 0; //打开蜂鸣器
delay_1ms(30); //短暂延时
beep = 1; //关闭蜂鸣器
}
void Outside_Int1(void) interrupt 0 using 1 //打开外部中断处理函数 优点,进入设置界面可以快速响应,避免长时间等待
{
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() //对里面的数值进行修改
{
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按键,系统设置值恢复初始值
{
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() //独立按键程序
{
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(); //保存数据
voice(); //提示音
}
}
if(!K3) //
{
delay_1ms(100);
if(!K3)
{
;
if(yemian==1)
{
if(s_dengji>1) { s_dengji--; } //浓度设置数减1
LCD_Show3(5,1,s_dengji);
}
if(yemian==2)
{
if(Temp_H>1) { Temp_H--; } //浓度设置数减1
LCD_Show2(7,1,Temp_H);
}
if(yemian==3)
{
if(Temp_L>1) { Temp_L--; } //浓度设置数减1
LCD_Show2(7,1,Temp_L);
}
if(yemian==4)
{
if(Humi_H>1) { Humi_H--; } //浓度设置数减1
LCD_Show2(7,1,Humi_H);
}
if(yemian==5)
{
if(Humi_L>1) { Humi_L--; } //浓度设置数减1
LCD_Show2(7,1,Humi_L);
}
write_eeprom(); //保存数据
voice(); //提示音
}
}
}
//****************报警函数*************
void baojing()
{
if(DUST >= s_dengji || TH>=Temp_H || TH<=Temp_L || RH>=Humi_H || RH<=Humi_L ) //报警
{
beep = ~beep; //蜂鸣器报警
}
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) //开机后程序运行5次再启动蜂鸣器功能
//开机报警功能等待温度湿度PM2.5数据处理完成再启动,避免蜂鸣器开机就乱叫。
{
time2=6;
baojing();
}
wenshidu();
if(yemian==0)
{
Delay_10us();
TL0 = (65536-30000)/256;
TH0 = (65536-30000)%256;
TR0 = 1; //开启定时器0
FlagStart=0;
}
}
}
void main()
{
init_eeprom();
LCD_Init(); //液晶初始化
LCD_Clear();//清屏
LCD_Write_String(4,0,"Welcome");
delay_ms(2000);
Timer0_Init(); //定时器0初始化
while(1)
{
key(); //独立按键程序
//====================yemian==0时 进入工作状态=================================
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; //开启定时器0
EA = 1;
}
chengxu();//主界面处理程序
}
//====================yemian==1时 ======PM2.5报警值========================
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时 温度上限==============================
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时 温度下限==============================
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时 湿度上限==============================
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时 湿度下限==============================
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);
}
}
}
复制代码
51hei.png
(9.44 KB, 下载次数: 75)
下载附件
2021-5-14 15:28 上传
以上代码下载:
PM2.5+温湿度程序.rar
(86.7 KB, 下载次数: 45)
2021-5-14 15:08 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
a1s2d3f4555
时间:
2022-3-26 16:42
大佬有原理图吗?想看看
作者:
Brussino
时间:
2024-4-25 15:36
您好我想请问一下,我的温湿度没有问题,但是PM没有显示是为什么呢
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1