現在空氣污染很嚴重,尤其是北方地區,所以某一個寶買了一套PM2.5、光照、溫濕度及時間一體的散件,自己做了成品。
IMG_20170321_103909.jpg (1.55 MB, 下載次數: 132)
下載附件
2017-3-21 10:46 上傳
時鐘芯片DS1302,精度一般般,準備換DS3231了。
溫濕度芯片DHT11,這個精度更差,準備換DHT22
光照芯片BH1750FVI。
單片機89C52
屏幕是串口并口通用的12864屏
PM2.5檢測原理圖:
0.png (109.27 KB, 下載次數: 130)
下載附件
2017-3-21 18:34 上傳
0.png (46.98 KB, 下載次數: 148)
下載附件
2017-3-21 18:25 上傳
單片機源程序:
- #include <reg52.h>
- #include <intrins.h>
- #include "12864.h"
- #include "ds1302.h"
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
- uint wendu=0; //溫度變量
- uint shidu=0; //濕度變量
- uint pm25=0; //pm2.5變量
- uint stwendu=30; //溫度報警變量
- uint stguang=100; //光照報警變量
- uint stpm25=100; //pm2.5報警變量
- uchar hor,min,sec; //時分秒
- uchar initial_time[]={0x00,0x00,0x00}; //時分秒設定
- unsigned int guangzhao=0; //光照變量
- float xdata guang=0; //光照變量
- sbit DQ=P1^0; //DHT11 單片機引腳
- sbit SCL=P2^0; //IIC時鐘引腳定義 讀取光照用
- sbit SDA=P2^1; //IIC數據引腳定義
- sbit k1=P3^2; //+ 按鍵
- sbit k2=P3^3; //-
- sbit k3=P3^4; //設置
- sbit led1=P1^5; //wendu baojing
- sbit led2=P1^6; // guangzhao baojing
- sbit led3=P1^7; //pm2.5baojing
- sbit fmq=P0^0; //pm2.5baojing
- uchar BUF[8]; //接收數據緩存區
- unsigned char xdata dat[6]; //串口變量 用于讀取pm2.5
- unsigned char k=0;
- unsigned char flagcom=0;
- unsigned char xdata ge,shi,bai,qian,wan; //顯示變量
- #define SlaveAddress 0x46 //定義器件在IIC總線中的從地址,根據ALT ADDRESS地址引腳不同修改
- //ALT ADDRESS引腳接地時地址為0x46,接電源時地址為0x3A
- //*****************************************長延時*****************************************
- void Delay(unsigned int s)
- {
- unsigned int i;
- for(i=0; i<s; i++);
- for(i=0; i<s; i++);
- }
- void Delay5us()
- {
- _nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();
- _nop_();_nop_();_nop_();_nop_();
- }
- void Delay5ms()
- {
- WORD n = 560;
- while (n--);
- }
- //**************************延時函數
- void delay_ms(unsigned int k)
- {
- unsigned int i,j;
- for(i=0;i<k;i++)
- {
- for(j=0;j<121;j++)
- {;}}
- }
- //溫濕度讀取
- //初始化DTH11
- bit Init_DTH11()
- {
- bit flag;
- uchar num;
- DQ=0;
- delay_ms(20); // >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)
- {
- shidu=DTH11_RD_CHAR(); //
- DTH11_RD_CHAR();
- wendu=DTH11_RD_CHAR();
- // tem=30;
- DTH11_RD_CHAR();
- DTH11_RD_CHAR();
- for(num=0;num<17;num++); //最后BIT輸出后拉低總線50us
- DQ=1;
- }
- }
- //********************************iic 光照///////////////////////////////////////////
- //***************************************************************************************
- /**************************************
- 起始信號
- **************************************/
- void BH1750_Start()
- {
- SDA = 1; //拉高數據線
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SDA = 0; //產生下降沿
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- }
- /**************************************
- 停止信號
- **************************************/
- void BH1750_Stop()
- {
- SDA = 0; //拉低數據線
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SDA = 1; //產生上升沿
- Delay5us(); //延時
- }
- /**************************************
- 發送應答信號
- 入口參數:ack (0:ACK 1:NAK)
- **************************************/
- void BH1750_SendACK(bit ack)
- {
- SDA = ack; //寫應答信號
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- /**************************************
- 接收應答信號
- **************************************/
- bit BH1750_RecvACK()
- {
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- CY = SDA; //讀應答信號
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- return CY;
- }
- /**************************************
- 向IIC總線發送一個字節數據
- **************************************/
- void BH1750_SendByte(BYTE dat)
- {
- BYTE i;
- for (i=0; i<8; i++) //8位計數器
- {
- dat <<= 1; //移出數據的最高位
- SDA = CY; //送數據口
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- BH1750_RecvACK();
- }
- /**************************************
- 從IIC總線接收一個字節數據
- **************************************/
- BYTE BH1750_RecvByte()
- {
- BYTE i;
- BYTE dat = 0;
- SDA = 1; //使能內部上拉,準備讀取數據,
- for (i=0; i<8; i++) //8位計數器
- {
- dat <<= 1;
- SCL = 1; //拉高時鐘線
- Delay5us(); //延時
- dat |= SDA; //讀數據
- SCL = 0; //拉低時鐘線
- Delay5us(); //延時
- }
- return dat;
- }
- //*********************************
- void Single_Write_BH1750(uchar REG_Address)
- {
- BH1750_Start(); //起始信號
- BH1750_SendByte(SlaveAddress); //發送設備地址+寫信號
- BH1750_SendByte(REG_Address); //內部寄存器地址,請參考中文pdf22頁
- // BH1750_SendByte(REG_data); //內部寄存器數據,請參考中文pdf22頁
- BH1750_Stop(); //發送停止信號
- }
- //********單字節讀取*****************************************
- /*
- uchar Single_Read_BH1750(uchar REG_Address)
- { uchar REG_data;
- BH1750_Start(); //起始信號
- BH1750_SendByte(SlaveAddress); //發送設備地址+寫信號
- BH1750_SendByte(REG_Address); //發送存儲單元地址,從0開始
- BH1750_Start(); //起始信號
- BH1750_SendByte(SlaveAddress+1); //發送設備地址+讀信號
- REG_data=BH1750_RecvByte(); //讀出寄存器數據
- BH1750_SendACK(1);
- BH1750_Stop(); //停止信號
- return REG_data;
- }
- */
- //*********************************************************
- //
- //連續讀出BH1750內部數據
- //
- //*********************************************************
- void Multiple_read_BH1750(void)
- { uchar i;
- BH1750_Start(); //起始信號
- BH1750_SendByte(SlaveAddress+1); //發送設備地址+讀信號
-
- for (i=0; i<3; i++) //連續讀取6個地址數據,存儲中BUF
- {
- BUF[i] = BH1750_RecvByte(); //BUF[0]存儲0x32地址中的數據
- if (i == 3)
- {
- BH1750_SendACK(1); //最后一個數據需要回NOACK
- }
- else
- {
- BH1750_SendACK(0); //回應ACK
- }
- }
- BH1750_Stop(); //停止信號
- Delay5ms();
- }
- //初始化BH1750,根據需要請參考pdf進行修改****
- void Init_BH1750()
- {
- Single_Write_BH1750(0x01);
- }
- void conversion(unsigned int temp_data) // 數據轉換出 個,十,百,千,萬
- {
- wan=temp_data/10000 ;
- qian=temp_data%10000/1000;
- bai=temp_data%1000/100;
- shi= temp_data%100/10;
- ge= temp_data%10;
- }
- /********************************************************************
- du1302 讀取時間
- ***********************************************************************/
- void du_ds1302()
- {
- uchar k;
-
- // uchar taddr = 0x81;
- // for (k=0; k<3; k++)
- // {
- // now_time[k] = read_data_ds1302(taddr);/*格式為: 秒 分 時 日 月 星期 年 */
- // taddr+= 2;
- // }
- k= read_data_ds1302(0x81);
- k=bcd16(k);
- if(k<60) sec=k;
- if(k>=60){write_data_ds1302(0x8e,0x00); write_data_ds1302(0x80,0);write_data_ds1302(0x8e,0x80); }
- k= read_data_ds1302(0x83);
- k=bcd16(k);
- if(k<60)min=k;
- k=read_data_ds1302(0x85);
- k=bcd16(k);
- if(k<24) hor=k;
- }
- void xianshishijian() //顯示時間
- {
-
- LCD_Setaddress(1,1);
- print("時間");
- LCD_write_dat(':');
- LCD_write_dat(hor/10+0x30);
- LCD_write_dat(hor%10+0x30);
- LCD_write_dat('-');
- LCD_write_dat(min/10+0x30);
- LCD_write_dat(min%10+0x30);
- LCD_write_dat('-');
- LCD_write_dat(sec/10+0x30);
- LCD_write_dat(sec%10+0x30);
-
- }
- xianshiwsd()//顯示溫濕度
- {
- LCD_Setaddress(2,1);
- //if(wendu>=99)wendu=99;
- print("溫度");
- LCD_write_dat(':');
- LCD_write_dat(wendu/10+0x30);
- LCD_write_dat(wendu%10+0x30);
- LCD_write_dat(' ');
- LCD_Setaddress(2,5);
- print("濕度");
- LCD_write_dat(':');
- LCD_write_dat(shidu/10+0x30);
- LCD_write_dat(shidu%10+0x30);
- LCD_write_dat('%');
- // LCD_write_dat(' ');
- }
- void xianshipm() //顯示pm2.5
- {
- if(pm25>=999)pm25=999;
- LCD_Setaddress(3,1);
- print("PM2.5");
- LCD_write_dat(':');
- LCD_write_dat(pm25/100+0x30);
- LCD_write_dat(pm25%100/10+0x30);
- LCD_write_dat(pm25%10+0x30);
- LCD_write_dat('u');
- LCD_write_dat('g');
- LCD_write_dat('/');
- LCD_write_dat('m');
- LCD_write_dat('3');
- LCD_write_dat(' ');
- LCD_write_dat(' ');
- }
- void xianshiguangzhao() //顯示光照
- {
- LCD_Setaddress(4,1);
- print("光照");
- LCD_write_dat(':');
- LCD_write_dat(wan+0x30);
- LCD_write_dat(qian+0x30);
- LCD_write_dat(bai+0x30);
- LCD_write_dat(shi+0x30);
- LCD_write_dat(ge+0x30);
- LCD_write_dat(' ');
- LCD_write_dat('L');
- LCD_write_dat('X');
- }
- void baojing()
- {
- if(wendu>stwendu) led1=0;
- else led1=1;
- if(guang<stguang) led2=0;
- else led2=1;
- if(pm25>stpm25)
- {
- led3=0;
- fmq=0;
-
-
- }
- else
- {
- led3=1;
- fmq=1;
- }
- }
- //////////////////////串口、、、、、、、、、、、、、用來讀取 pm2.5/////////////////////////////////////////////////
- void UartInit(void) //2400bps@11.0592MHz
- {
- SCON = 0x50; //8-bit variable UART
- PCON=0X00;
- TMOD = 0x20; //Set Timer1 as 8-bit auto reload mode
- TH1 = TL1 = 0XF4; //Set auto-reload vaule
- TR1 = 1; //Timer1 start run
- ES = 0; //Enable UART interrupt
- EA = 0; //Open master interrupt switch
- }
- void SendByte(unsigned char dat)
- {
- SBUF = dat;
- while(!TI);
- TI = 0;
- }
- void UART_SER (void) interrupt 4
- {
-
- uint aa;
- if (RI)
- {
- RI = 0; //Clear receive interrupt flag
-
- dat[k]= SBUF; //P0 show UART data
- if(dat[0]!=0xaa) k=0;
- else k++;
- if((dat[0]==0xaa)&&(k>5)) //讀取pm2.5數據
- {
-
- ES=0;
- EA=0;
- aa=dat[1]*255+dat[2];
- if(aa!=0) pm25=aa;
- flagcom=0;
- Delay(2000);
-
- k=0;
- }
- }
- if (TI)
- {
- TI = 0; //Clear transmit interrupt flag
- }
- }
- //************************************主函數************************************************************
- void main(void)
- {
- uint flaga=0; //pm2.5傳感器 串口無法讀取時正常顯示其它數據標志
- unsigned char aa; //按鍵切換標志
- //上電延時
- Delay(6000); //初始化時鐘
- init_ds1302(); //時鐘初始化
- LCD_draw_clr(); //屏幕復位
- k1=1; //按鍵引腳拉高
- k2=1;
- k3=1;
- Init_BH1750(); //初始化BH1750
- flagcom=0; //串口中斷 標志
- UartInit() ;
- aa=0;
- while(1)
- {
-
- if(k3==0) //設置按鍵計數
- {
- Delay(10000);
- if(k3==0)
- {
-
- aa++;
- Delay(2000);
- }
-
- }
- if((flagcom==0)&(aa==0)) //循環讀取數據 flagcom 串口中斷標志 aa按鍵標志
- {
- Delay(500);
- du_ds1302() ; //讀取1302時間
- Delay(500);
- xianshishijian(); //顯示時間
-
-
- Delay(2000);
- DTH11_DUSHU(); //溫度濕度讀取
- Delay(100);
-
- xianshiwsd(); // 顯示溫度濕度
- Delay(1000);
- xianshipm(); //顯示pm2.5
- Delay(1000);
- Single_Write_BH1750(0x01); // 讀取 光照
- Single_Write_BH1750(0x10); // H- resolution mode
- Delay(180); //延時
- Multiple_Read_BH1750(); //連續讀出數據,存儲在BUF中
- guangzhao=BUF[0];
- guangzhao=(guangzhao<<8)+BUF[1];//合成數據
- guang=(float)guangzhao/1.2;
- conversion(guang) ;
- xianshiguangzhao(); //顯示光照
- baojing(); //報警函數
-
- Delay(500);
- flaga=0;
- flagcom=1;
- ES=1;
- EA=1;
- Delay(500);
- }
- Delay(500);
- flaga++;
- if(flaga>=10)
- {
- flagcom=0;
- flaga=0;
-
- }
- //設置baojingzhi
-
-
- if(aa>5) aa=0;
- if(aa==1)
- {
- Delay(5000) ;
- LCD_Setaddress(1,1);
- print(" 設置 ");
- LCD_Setaddress(2,1);
- print("溫度報警:");
-
- conversion(stwendu);
-
- LCD_write_dat(shi+0x30);
- LCD_write_dat(ge+0x30);
- LCD_write_dat(' ');
- LCD_write_dat(' ');
- LCD_write_dat(' ');
- LCD_write_dat(' ');
- LCD_write_dat(' ');
- LCD_Setaddress(3,1);
- print(" ");
- LCD_Setaddress(4,1);
- print(" ");
- if(k1==0)
- { Delay(500) ;
- if(k1==0)
- {
- stwendu++;
- }
- }
- if(k2==0)
- { Delay(500) ;
- if(k2==0)
- {
- stwendu--;
- }
- }
-
- }
- if(aa==2)
- {
- LCD_Setaddress(1,1);
- print(" 設置 ");
- LCD_Setaddress(2,1);
- print("光照報警:");
-
- conversion(stguang);
- LCD_write_dat(wan+0x30);
- LCD_write_dat(qian+0x30);
- LCD_write_dat(bai+0x30);
- LCD_write_dat(shi+0x30);
- LCD_write_dat(ge+0x30);
- LCD_write_dat(' ');
- LCD_Setaddress(3,1);
- print(" ");
- LCD_Setaddress(4,1);
- print(" ");
- if(k1==0)
- { Delay(500) ;
- if(k1==0)
- {
- stguang++;
- }
- }
- if(k2==0)
- { Delay(500) ;
- if(k2==0)
- {
- stguang--;
- }
- }
-
- }
- if(aa==3)
- {
- LCD_Setaddress(1,1);
- print(" 設置 ");
- LCD_Setaddress(2,1);
- print("PM2.5 ");
- LCD_Setaddress(2,4);
- print("報警:");
- …………余下代碼請下載附件…………
復制代碼
原理圖等資料:
SHEET1.pdf
(289.29 KB, 下載次數: 151)
2017-3-21 10:46 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
BH1750FVI.pdf
(386.29 KB, 下載次數: 128)
2017-3-21 10:46 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
CN_DS1302.pdf
(205.99 KB, 下載次數: 86)
2017-3-21 10:47 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
DHT11濕溫度傳感器使用范例.pdf
(388 KB, 下載次數: 116)
2017-3-21 10:47 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
QC12864B.pdf
(352.95 KB, 下載次數: 113)
2017-3-21 10:47 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
育松電子 QC12864B使用說明.pdf
(285.61 KB, 下載次數: 106)
2017-3-21 10:47 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
源碼下載:
程序.rar
(12.44 KB, 下載次數: 377)
2017-3-21 10:47 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|