- #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);
- }
-
- }
-
- }
复制代码
以上代码下载:
PM2.5+温湿度程序.rar
(86.7 KB, 下载次数: 45)
|