找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 15401|回復(fù): 9
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)+GP2Y1014AU pm2.5測量+DHT11溫濕度仿真設(shè)計(jì)源碼

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
    這個(gè)單片機(jī)程序目前是顯示PM2.5,溫濕度,PM2.5傳感器用的是GP2Y1014AU(模擬輸出),溫濕度用的是DHT11(數(shù)字輸出),有個(gè)問題就是當(dāng)K=Adc0832();這句放到中斷里面,溫濕度會變化,但是PM2.5就沒有值,不會自己變化,得按一下復(fù)位鍵才顯示值,當(dāng)K=Adc0832();這句放到主函數(shù)里面,PM2.5就有值變化,但是溫濕度的值沒有了,按復(fù)位鍵也沒有值。開始我懷疑中斷函數(shù)影響了液晶屏的時(shí)序,但是后面直接給一個(gè)K值,PM2.5和溫濕度都會變,我就找不到是哪里的問題了。有沒有大神能幫忙看看是哪里的問題,程序和仿真圖都在附件里。

PM2.5驅(qū)動條件:
關(guān)于驅(qū)動條件
根據(jù)LED驅(qū)動周期(脈沖周期:T (ms) ),LED驅(qū)動時(shí)間(脈沖:寬度Pw(ms) )輸出電壓會變動,規(guī)格書特性的規(guī)格值是脈沖周期T:10ms,脈沖寬度Pw:0.32ms,取樣時(shí)間:0.28ms,根據(jù)此條件變動,規(guī)格書上規(guī)定的特性值(無塵時(shí)輸出電壓、檢出感度)也隨之變動。
   

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機(jī)源程序如下:
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4.   int temp;
  5. typedef unsigned int u16;          //對數(shù)據(jù)類型進(jìn)行聲明定義
  6. typedef unsigned char u8;
  7. sbit LCDE=P1^2;
  8. sbit RS=P1^0;
  9. sbit RW=P1^1;
  10. sbit ADCS=P2^0;  //ADC0832 chip seclect
  11. sbit ADDO=P3^7;  //ADC0832 k in
  12. sbit ADDI=P3^7;  //ADC0832 k in
  13. sbit ADCLK=P3^6;  //ADC0832 clock signal
  14. sbit DHTIO=P2^1; //DHT11輸出
  15. sbit LED=P2^7;        //LED脈沖驅(qū)動
  16. unsigned char code digit[10]={"0123456789"};
  17. volatile   uchar  K=0;//AD轉(zhuǎn)換數(shù)字量
  18.    uint tempshi,tempge,humshi,humge;
  19. unsigned char  U8FLAG=0,U8temp=0;
  20. unsigned char  U8T_data_H=0,U8T_data_L=0,U8RH_data_H=0,U8RH_data_L=0,U8checkdata=0;
  21. unsigned char str[5];

  22. //humidity 濕度  
  23. //temperature 溫度  
  24. //integer 整數(shù)  
  25. //decimal 小數(shù)  
  26. unsigned char humidity_interger=0,humidity_decimal;  
  27. unsigned char temperature_integer=0,temperature_decimal;  
  28. unsigned char check;  
  29.   void delay(unsigned int z) //延時(shí)長
  30. {
  31.          unsigned char x,y;
  32.          for(x=z;x>0;x--)
  33.          {
  34.                  for(y=20;y>0;y--);
  35.          }
  36. }
  37. void delay40us()  
  38. {  
  39.      unsigned char a,b;  
  40.      for(b=3;b>0;b--)  
  41.         for(a=4;a>0;a--);  
  42. }  

  43.   void delayms(uint del)  
  44. {
  45. uint u,v;
  46. for(u=0;u<del;u++)
  47.    for(v=0;v<=100;v++);
  48. }

  49. void delay20ms()  
  50. {  
  51.     unsigned char a,b,c;  
  52.     for(c=1;c>0;c--)  
  53.         for(b=222;b>0;b--)  
  54.             for(a=40;a>0;a--);  
  55. }  
  56. unsigned char Adc0832()     //AD轉(zhuǎn)換,返回結(jié)果
  57. {
  58.            uchar u=0;
  59.    
  60.     uchar dat=0;

  61.         ADCLK=0;
  62.          delayms(1);
  63.         ADCS=0;//拉低CS端
  64.      delayms(1);
  65.     ADDI=1;
  66.     delayms(1);
  67.     ADCLK=1;//拉高CLK端
  68.    delayms(1);
  69.     ADCLK=0;//拉低CLK端,形成下降沿1
  70.    delayms(1);
  71.     ADCLK=1;//拉高CLK端
  72.     ADDI=1;
  73.     delayms(1);
  74.     ADCLK=0;//拉低CLK端,形成下降沿2
  75.    delayms(1);
  76.     ADCLK=1;//拉高CLK端
  77.     ADDI=1;
  78.    delayms(1);
  79.     ADCLK=0;//拉低CLK端,形成下降沿3
  80.    delayms(1);
  81.     ADDI=1;//控制命令結(jié)束
  82.     delayms(1);
  83.     dat=0;
  84.     for(u=0;u<8;u++)
  85.     {       
  86.                 ADCLK=1;
  87.          delayms(1);
  88.                 ADCLK=0;//形成一次時(shí)鐘脈沖
  89.                delayms(1);
  90.                         dat|=ADDO;//收數(shù)據(jù)
  91.                         if(u<7)
  92.                 dat<<=1;
  93.     }  
  94.     for(u=0;u<8;u++)
  95.     {
  96.         
  97.         ADCLK=1;
  98.       delayms(1);
  99.         ADCLK=0;//形成一次時(shí)鐘脈沖
  100.        delayms(1);
  101.     }
  102.     ADCS=1;//拉低CS端
  103.     ADCLK=0;//拉低CLK端
  104.     ADDO=1;//拉高數(shù)據(jù)端,回到初始狀態(tài)
  105.    
  106.     return dat;            //return ad k
  107.        
  108. }  
  109. void dht_start()             //等待接受初始化
  110. {  
  111.      DHTIO=1;          //初始高電平  
  112.      delay40us();  
  113.      DHTIO=0;          //主機(jī)拉低電平  
  114.      delay20ms();      //保持電平時(shí)間大于18ms  
  115.      DHTIO=1;          //主機(jī)拉高電平  
  116.      delay40us();      //延遲等待20-40us等待從機(jī)響應(yīng)  
  117. }  
  118.   
  119. unsigned char recieve_data() //數(shù)據(jù)接收
  120. {  
  121.     unsigned char i,flag,data_byte;  
  122.     for(i=0;i<8;i++)  
  123.     {  
  124.         flag=2;  
  125.         while((!DHTIO)&&flag++);//等待從機(jī)發(fā)出50us低電平結(jié)束  
  126.         delay40us();            //延時(shí)超過26us-28us不超過70us  
  127.         data_byte=data_byte<<1;  
  128.         if(DHTIO)                 //如果此時(shí)dhtio為1則表示此時(shí)從機(jī)輸出數(shù)據(jù)為1否則說明此時(shí)從機(jī)輸出數(shù)據(jù)為0  
  129.         {  
  130.             data_byte|=0x01;  
  131.             flag=2;  
  132.             while((DHTIO)&&flag++);//等待剩下的高電平結(jié)束  
  133.         }  
  134.         if(!flag)  
  135.             break;  
  136.     }                   
  137.     return data_byte;  
  138. }  
  139. void dht_take_sample()     //采樣
  140. {  
  141.      unsigned char flag;  
  142.      dht_start();  
  143.      if(!DHTIO)         //從機(jī)發(fā)出響應(yīng)信號  
  144.      {  
  145.           flag=2;  
  146.           while((!DHTIO)&&flag++);//檢測從機(jī)發(fā)出80us低電平是否結(jié)束  
  147.           flag=2;  
  148.           while((DHTIO)&&flag++); //檢測從機(jī)發(fā)出80us高電平是否結(jié)束  
  149.           //開始采集數(shù)據(jù)  
  150.           humidity_interger=recieve_data();     //采集濕度整數(shù)部分  
  151.           humidity_decimal=recieve_data();      //采集濕度小數(shù)部分  
  152.           temperature_integer=recieve_data();   //采集溫度整數(shù)部分  
  153.           temperature_decimal=recieve_data();   //采集溫度小數(shù)部分  
  154.           check=recieve_data();                 //采集校驗(yàn)位  
  155.             
  156.           DHTIO=1;  //采集數(shù)據(jù)后主機(jī)拉高電平  
  157.      }  
  158. }  







  159. void write_com(unsigned char com)   //將模式設(shè)置指令或顯示地址寫入液晶模塊
  160. {
  161.          RS=0;
  162.          RW=0;
  163.          LCDE=0;
  164.          P0=com;
  165.          delay(5);
  166.          LCDE=1;
  167.          delay(5);
  168.          LCDE=0;
  169. }
  170. void write_date(unsigned char date)//將數(shù)據(jù)(字符ASCII碼)寫入液晶模塊
  171. {
  172.          RS=1;
  173.          RW=0;
  174.          LCDE=0;
  175.          P0=date;
  176.          delay(5);
  177.          LCDE=1;
  178.          delay(5);
  179.          LCDE=0;
  180. }
  181. void L1602_string(unsigned char hang,unsigned char lie,unsigned char p)   //將數(shù)據(jù)寫入液晶模塊
  182. {
  183.         unsigned char a;
  184.         if(hang == 1) a = 0x80;                                         //顯示在第一行
  185.         if(hang == 2) a = 0xc0;                                         //顯示在第一行
  186.         a = a + lie -1;
  187.         write_com(a);
  188.         write_date(p);
  189. }
  190. void init()                         //1602初始化
  191. {
  192.          write_com(0x38);
  193.          write_com(0x0e);
  194.          write_com(0x06);
  195.          write_com(0x01);
  196.          write_com(0x80);
  197. }


  198. void xianshi1()          //pm2.5顯示
  199. {
  200.        
  201.        
  202.     L1602_string(1,1,'P');
  203.     L1602_string(1,2,'M');
  204.     L1602_string(1,3,'2');
  205.     L1602_string(1,4,'.');
  206.     L1602_string(1,5,'5');
  207.         L1602_string(1,6,':');
  208.         L1602_string(1,7,' ');
  209.        
  210.         L1602_string(1,8,K/100+0x30);
  211.         L1602_string(1,9,(K-100*(K/100))/10+0x30);
  212.         L1602_string(1,10,K%10+0x30);
  213.         L1602_string(1,11,' ');
  214.         L1602_string(1,12,'u');
  215.         L1602_string(1,13,'g');
  216.         L1602_string(1,14,'/');                               
  217.         L1602_string(1,15,'m');       
  218.         L1602_string(1,16,'3');

  219.     L1602_string(2,1,'T');
  220.         L1602_string(2,2,'e');
  221.         L1602_string(2,3,'m');
  222.         L1602_string(2,4,'p');
  223.         L1602_string(2,5,':');
  224.         L1602_string(2,6,digit[tempshi]);
  225.     L1602_string(2,7,digit[tempge]);       
  226.         L1602_string(2,8,'C');
  227.         L1602_string(2,9,' ');
  228.         L1602_string(2,10,'H');
  229.         L1602_string(2,11,'u');
  230.         L1602_string(2,12,'m');
  231.         L1602_string(2,13,':');
  232.         L1602_string(2,14,digit[humshi]);
  233.                 //L1602_string(2,14,(K-100*(K/100))/10+0x30);
  234.         L1602_string(2,15,digit[humge]);
  235.         //L1602_string(2,15,K%10+0x30);
  236.         L1602_string(2,16,'%');
  237. }
  238. void readDH() //溫濕度讀取
  239. {                  
  240.                  dht_start();
  241.                  recieve_data();
  242.                  dht_take_sample();
  243.                  humshi=humidity_interger/10;
  244.                  humge=humidity_interger%10;
  245.                  tempshi=temperature_integer/10;
  246.                  tempge=temperature_integer%10;
  247. }

  248. void Timer0Init()
  249. {  
  250.     RW=0;
  251.     LED=0;
  252.         TMOD|=0X01;//選擇為定時(shí)器0模式,工作方式1,僅用TR0打開啟動。
  253.         TH0=(65536-10000)%256;
  254.         TL0=(65536-10000)/256; //定時(shí)10ms        
  255.         ET0=1;//打開定時(shí)器0中斷允許
  256.         EA=1;//打開總中斷
  257.         TR0=1;//打開定時(shí)器       
  258.                
  259. }

  260. void main()           //主函數(shù)
  261. {               
  262.                   int liu=0;
  263.                   LCDE=0;
  264.          init();
  265.                 Timer0Init();
  266.                  
  267.          while(1)
  268.          {
  269.                
  270.                            //liu++;
  271.                         // if(liu==245)
  272.                          //liu=0;
  273.                         // K=Adc0832();
  274.                          readDH();
  275.                           xianshi1();
  276.                  }
  277. }

  278. /**************************************
  279. /*****定時(shí)器0中斷服務(wù)程序****/
  280. void Timer0() interrupt 1
  281. {
  282.         static u16 j;
  283.    
  284.                    // temp++;
  285. TH0 = (65536-10000)%256;   
  286. TL0 = (65536-10000)/256;     
  287.   
  288.      LED=1;
  289.       //開啟傳感器的LED
  290.      for (j=0;j<222;j++);  //0.28ms  //延時(shí)0.28ms
  291.                    K=Adc0832();  //開啟ADC采集
  292.         /*        if(temp==20){
  293.                          K+=40;
  294.                         temp=0;
  295.                 }          */
  296.                 //if(K>240)
  297.                 //K=0;
  298.                      //xianshi1();
  299.           TR0 = 0;   //先關(guān)閉定時(shí)器0
  300.      EA = 0;
  301.           
  302. LED=0;
  303. }  
  304.          
復(fù)制代碼


所有資料51hei提供下載:
壓縮文件.rar (75.7 KB, 下載次數(shù): 462)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:272459 發(fā)表于 2018-5-17 15:09 | 只看該作者
你AD值都沒傳出來,K=adc0832()  K要么是0 要么是1;
回復(fù)

使用道具 舉報(bào)

板凳
ID:327052 發(fā)表于 2018-5-17 18:03 | 只看該作者
abcarry 發(fā)表于 2018-5-17 15:09
你AD值都沒傳出來,K=adc0832()  K要么是0 要么是1;

哥能發(fā)我一分嗎
回復(fù)

使用道具 舉報(bào)

地板
ID:130743 發(fā)表于 2019-3-11 09:14 | 只看該作者
感謝樓主分享
回復(fù)

使用道具 舉報(bào)

5#
ID:480151 發(fā)表于 2019-3-19 07:45 | 只看該作者
感謝樓主分享,有電路連接圖嗎?
回復(fù)

使用道具 舉報(bào)

6#
ID:521658 發(fā)表于 2019-4-27 19:51 | 只看該作者
仿真圖里沒有dht11和pm2.5的傳感器嗎
回復(fù)

使用道具 舉報(bào)

7#
ID:509243 發(fā)表于 2019-5-19 20:59 來自手機(jī) | 只看該作者
解決了嗎兄弟,我的pm怎么一直不顯示,能把新的發(fā)我一份哦啊,13122319913@163.com,謝謝
回復(fù)

使用道具 舉報(bào)

8#
ID:250245 發(fā)表于 2020-5-9 13:35 | 只看該作者
應(yīng)該是AD轉(zhuǎn)換是需要時(shí)間的,AD轉(zhuǎn)換放在定時(shí)器里面,導(dǎo)致你while循環(huán)的延時(shí)函數(shù)不準(zhǔn),DHT11無法滿足時(shí)序,可以將AD循環(huán)放在主函數(shù),定時(shí)器里面計(jì)數(shù),當(dāng)?shù)竭_(dá)0.28ms的時(shí)候AD轉(zhuǎn)換,然后在檢測DHT11,檢測完以后繼續(xù)等待下一個(gè)0.28ms
回復(fù)

使用道具 舉報(bào)

9#
ID:250245 發(fā)表于 2020-5-9 13:36 | 只看該作者
而且你定時(shí)器里還有一個(gè)280us的延時(shí),這個(gè)遠(yuǎn)遠(yuǎn)操過了DHT11的30和20us的延時(shí)
回復(fù)

使用道具 舉報(bào)

10#
ID:1112270 發(fā)表于 2024-3-11 13:59 | 只看該作者
請問你解決了嘛,我做pm2.5檢測,傳感器輸出電壓太低,沒有任何顯示
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表