這個單片機程序目前是顯示PM2.5,溫濕度,PM2.5傳感器用的是GP2Y1014AU(模擬輸出),溫濕度用的是DHT11(數字輸出),有個問題就是當K=Adc0832();這句放到中斷里面,溫濕度會變化,但是PM2.5就沒有值,不會自己變化,得按一下復位鍵才顯示值,當K=Adc0832();這句放到主函數里面,PM2.5就有值變化,但是溫濕度的值沒有了,按復位鍵也沒有值。開始我懷疑中斷函數影響了液晶屏的時序,但是后面直接給一個K值,PM2.5和溫濕度都會變,我就找不到是哪里的問題了。有沒有大神能幫忙看看是哪里的問題,程序和仿真圖都在附件里。
PM2.5驅動條件:
關于驅動條件
根據LED驅動周期(脈沖周期:T (ms) ),LED驅動時間(脈沖:寬度Pw(ms) )輸出電壓會變動,規格書特性的規格值是脈沖周期T:10ms,脈沖寬度Pw:0.32ms,取樣時間:0.28ms,根據此條件變動,規格書上規定的特性值(無塵時輸出電壓、檢出感度)也隨之變動。
2.png (1.04 MB, 下載次數: 98)
下載附件
溫濕度會自己變動,但是AD值不會自己變
2018-4-6 09:51 上傳
1.png (1018.63 KB, 下載次數: 97)
下載附件
AD采樣值會自己變動,但是溫濕度不會變
2018-4-6 09:50 上傳
3.png (1.05 MB, 下載次數: 85)
下載附件
溫濕度會自己變動,但是AD值不會自己變
2018-4-6 09:51 上傳
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (23.07 KB, 下載次數: 114)
下載附件
2018-4-6 16:01 上傳
單片機源程序如下:
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- int temp;
- typedef unsigned int u16; //對數據類型進行聲明定義
- typedef unsigned char u8;
- sbit LCDE=P1^2;
- sbit RS=P1^0;
- sbit RW=P1^1;
- sbit ADCS=P2^0; //ADC0832 chip seclect
- sbit ADDO=P3^7; //ADC0832 k in
- sbit ADDI=P3^7; //ADC0832 k in
- sbit ADCLK=P3^6; //ADC0832 clock signal
- sbit DHTIO=P2^1; //DHT11輸出
- sbit LED=P2^7; //LED脈沖驅動
- unsigned char code digit[10]={"0123456789"};
- volatile uchar K=0;//AD轉換數字量
- uint tempshi,tempge,humshi,humge;
- unsigned char U8FLAG=0,U8temp=0;
- unsigned char U8T_data_H=0,U8T_data_L=0,U8RH_data_H=0,U8RH_data_L=0,U8checkdata=0;
- unsigned char str[5];
- //humidity 濕度
- //temperature 溫度
- //integer 整數
- //decimal 小數
- unsigned char humidity_interger=0,humidity_decimal;
- unsigned char temperature_integer=0,temperature_decimal;
- unsigned char check;
- void delay(unsigned int z) //延時長
- {
- unsigned char x,y;
- for(x=z;x>0;x--)
- {
- for(y=20;y>0;y--);
- }
- }
- void delay40us()
- {
- unsigned char a,b;
- for(b=3;b>0;b--)
- for(a=4;a>0;a--);
- }
-
- void delayms(uint del)
- {
- uint u,v;
- for(u=0;u<del;u++)
- for(v=0;v<=100;v++);
- }
- void delay20ms()
- {
- unsigned char a,b,c;
- for(c=1;c>0;c--)
- for(b=222;b>0;b--)
- for(a=40;a>0;a--);
- }
- unsigned char Adc0832() //AD轉換,返回結果
- {
- uchar u=0;
-
- uchar dat=0;
- ADCLK=0;
- delayms(1);
- ADCS=0;//拉低CS端
- delayms(1);
- ADDI=1;
- delayms(1);
- ADCLK=1;//拉高CLK端
- delayms(1);
- ADCLK=0;//拉低CLK端,形成下降沿1
- delayms(1);
- ADCLK=1;//拉高CLK端
- ADDI=1;
- delayms(1);
- ADCLK=0;//拉低CLK端,形成下降沿2
- delayms(1);
- ADCLK=1;//拉高CLK端
- ADDI=1;
- delayms(1);
- ADCLK=0;//拉低CLK端,形成下降沿3
- delayms(1);
- ADDI=1;//控制命令結束
- delayms(1);
- dat=0;
- for(u=0;u<8;u++)
- {
- ADCLK=1;
- delayms(1);
- ADCLK=0;//形成一次時鐘脈沖
- delayms(1);
- dat|=ADDO;//收數據
- if(u<7)
- dat<<=1;
- }
- for(u=0;u<8;u++)
- {
-
- ADCLK=1;
- delayms(1);
- ADCLK=0;//形成一次時鐘脈沖
- delayms(1);
- }
- ADCS=1;//拉低CS端
- ADCLK=0;//拉低CLK端
- ADDO=1;//拉高數據端,回到初始狀態
-
- return dat; //return ad k
-
- }
- void dht_start() //等待接受初始化
- {
- DHTIO=1; //初始高電平
- delay40us();
- DHTIO=0; //主機拉低電平
- delay20ms(); //保持電平時間大于18ms
- DHTIO=1; //主機拉高電平
- delay40us(); //延遲等待20-40us等待從機響應
- }
-
- unsigned char recieve_data() //數據接收
- {
- unsigned char i,flag,data_byte;
- for(i=0;i<8;i++)
- {
- flag=2;
- while((!DHTIO)&&flag++);//等待從機發出50us低電平結束
- delay40us(); //延時超過26us-28us不超過70us
- data_byte=data_byte<<1;
- if(DHTIO) //如果此時dhtio為1則表示此時從機輸出數據為1否則說明此時從機輸出數據為0
- {
- data_byte|=0x01;
- flag=2;
- while((DHTIO)&&flag++);//等待剩下的高電平結束
- }
- if(!flag)
- break;
- }
- return data_byte;
- }
- void dht_take_sample() //采樣
- {
- unsigned char flag;
- dht_start();
- if(!DHTIO) //從機發出響應信號
- {
- flag=2;
- while((!DHTIO)&&flag++);//檢測從機發出80us低電平是否結束
- flag=2;
- while((DHTIO)&&flag++); //檢測從機發出80us高電平是否結束
- //開始采集數據
- humidity_interger=recieve_data(); //采集濕度整數部分
- humidity_decimal=recieve_data(); //采集濕度小數部分
- temperature_integer=recieve_data(); //采集溫度整數部分
- temperature_decimal=recieve_data(); //采集溫度小數部分
- check=recieve_data(); //采集校驗位
-
- DHTIO=1; //采集數據后主機拉高電平
- }
- }
- void write_com(unsigned char com) //將模式設置指令或顯示地址寫入液晶模塊
- {
- RS=0;
- RW=0;
- LCDE=0;
- P0=com;
- delay(5);
- LCDE=1;
- delay(5);
- LCDE=0;
- }
- void write_date(unsigned char date)//將數據(字符ASCII碼)寫入液晶模塊
- {
- RS=1;
- RW=0;
- LCDE=0;
- P0=date;
- delay(5);
- LCDE=1;
- delay(5);
- LCDE=0;
- }
- void L1602_string(unsigned char hang,unsigned char lie,unsigned char p) //將數據寫入液晶模塊
- {
- unsigned char a;
- if(hang == 1) a = 0x80; //顯示在第一行
- if(hang == 2) a = 0xc0; //顯示在第一行
- a = a + lie -1;
- write_com(a);
- write_date(p);
- }
- void init() //1602初始化
- {
- write_com(0x38);
- write_com(0x0e);
- write_com(0x06);
- write_com(0x01);
- write_com(0x80);
- }
- void xianshi1() //pm2.5顯示
- {
-
-
- L1602_string(1,1,'P');
- L1602_string(1,2,'M');
- L1602_string(1,3,'2');
- L1602_string(1,4,'.');
- L1602_string(1,5,'5');
- L1602_string(1,6,':');
- L1602_string(1,7,' ');
-
- L1602_string(1,8,K/100+0x30);
- L1602_string(1,9,(K-100*(K/100))/10+0x30);
- L1602_string(1,10,K%10+0x30);
- L1602_string(1,11,' ');
- L1602_string(1,12,'u');
- L1602_string(1,13,'g');
- L1602_string(1,14,'/');
- L1602_string(1,15,'m');
- L1602_string(1,16,'3');
- L1602_string(2,1,'T');
- L1602_string(2,2,'e');
- L1602_string(2,3,'m');
- L1602_string(2,4,'p');
- L1602_string(2,5,':');
- L1602_string(2,6,digit[tempshi]);
- L1602_string(2,7,digit[tempge]);
- L1602_string(2,8,'C');
- L1602_string(2,9,' ');
- L1602_string(2,10,'H');
- L1602_string(2,11,'u');
- L1602_string(2,12,'m');
- L1602_string(2,13,':');
- L1602_string(2,14,digit[humshi]);
- //L1602_string(2,14,(K-100*(K/100))/10+0x30);
- L1602_string(2,15,digit[humge]);
- //L1602_string(2,15,K%10+0x30);
- L1602_string(2,16,'%');
- }
- void readDH() //溫濕度讀取
- {
- dht_start();
- recieve_data();
- dht_take_sample();
- humshi=humidity_interger/10;
- humge=humidity_interger%10;
- tempshi=temperature_integer/10;
- tempge=temperature_integer%10;
- }
- void Timer0Init()
- {
- RW=0;
- LED=0;
- TMOD|=0X01;//選擇為定時器0模式,工作方式1,僅用TR0打開啟動。
- TH0=(65536-10000)%256;
- TL0=(65536-10000)/256; //定時10ms
- ET0=1;//打開定時器0中斷允許
- EA=1;//打開總中斷
- TR0=1;//打開定時器
-
- }
- void main() //主函數
- {
- int liu=0;
- LCDE=0;
- init();
- Timer0Init();
-
- while(1)
- {
-
- //liu++;
- // if(liu==245)
- //liu=0;
- // K=Adc0832();
- readDH();
- xianshi1();
- }
- }
- /**************************************
- /*****定時器0中斷服務程序****/
- void Timer0() interrupt 1
- {
- static u16 j;
-
- // temp++;
- TH0 = (65536-10000)%256;
- TL0 = (65536-10000)/256;
-
- LED=1;
- //開啟傳感器的LED
- for (j=0;j<222;j++); //0.28ms //延時0.28ms
- K=Adc0832(); //開啟ADC采集
- /* if(temp==20){
- K+=40;
- temp=0;
- } */
- //if(K>240)
- //K=0;
- //xianshi1();
- TR0 = 0; //先關閉定時器0
- EA = 0;
-
- LED=0;
- }
-
復制代碼
0.png (43.34 KB, 下載次數: 95)
下載附件
2018-4-6 16:01 上傳
所有資料51hei提供下載:
壓縮文件.rar
(75.7 KB, 下載次數: 462)
2018-4-6 09:52 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|