久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 15311|回復: 9
打印 上一主題 下一主題
收起左側

單片機+GP2Y1014AU pm2.5測量+DHT11溫濕度仿真設計源碼

  [復制鏈接]
跳轉到指定樓層
樓主
    這個單片機程序目前是顯示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,根據此條件變動,規格書上規定的特性值(無塵時輸出電壓、檢出感度)也隨之變動。
   

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


單片機源程序如下:
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4.   int temp;
  5. typedef unsigned int u16;          //對數據類型進行聲明定義
  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脈沖驅動
  16. unsigned char code digit[10]={"0123456789"};
  17. volatile   uchar  K=0;//AD轉換數字量
  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 整數  
  25. //decimal 小數  
  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) //延時長
  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轉換,返回結果
  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;//控制命令結束
  82.     delayms(1);
  83.     dat=0;
  84.     for(u=0;u<8;u++)
  85.     {       
  86.                 ADCLK=1;
  87.          delayms(1);
  88.                 ADCLK=0;//形成一次時鐘脈沖
  89.                delayms(1);
  90.                         dat|=ADDO;//收數據
  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;//形成一次時鐘脈沖
  100.        delayms(1);
  101.     }
  102.     ADCS=1;//拉低CS端
  103.     ADCLK=0;//拉低CLK端
  104.     ADDO=1;//拉高數據端,回到初始狀態
  105.    
  106.     return dat;            //return ad k
  107.        
  108. }  
  109. void dht_start()             //等待接受初始化
  110. {  
  111.      DHTIO=1;          //初始高電平  
  112.      delay40us();  
  113.      DHTIO=0;          //主機拉低電平  
  114.      delay20ms();      //保持電平時間大于18ms  
  115.      DHTIO=1;          //主機拉高電平  
  116.      delay40us();      //延遲等待20-40us等待從機響應  
  117. }  
  118.   
  119. unsigned char recieve_data() //數據接收
  120. {  
  121.     unsigned char i,flag,data_byte;  
  122.     for(i=0;i<8;i++)  
  123.     {  
  124.         flag=2;  
  125.         while((!DHTIO)&&flag++);//等待從機發出50us低電平結束  
  126.         delay40us();            //延時超過26us-28us不超過70us  
  127.         data_byte=data_byte<<1;  
  128.         if(DHTIO)                 //如果此時dhtio為1則表示此時從機輸出數據為1否則說明此時從機輸出數據為0  
  129.         {  
  130.             data_byte|=0x01;  
  131.             flag=2;  
  132.             while((DHTIO)&&flag++);//等待剩下的高電平結束  
  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)         //從機發出響應信號  
  144.      {  
  145.           flag=2;  
  146.           while((!DHTIO)&&flag++);//檢測從機發出80us低電平是否結束  
  147.           flag=2;  
  148.           while((DHTIO)&&flag++); //檢測從機發出80us高電平是否結束  
  149.           //開始采集數據  
  150.           humidity_interger=recieve_data();     //采集濕度整數部分  
  151.           humidity_decimal=recieve_data();      //采集濕度小數部分  
  152.           temperature_integer=recieve_data();   //采集溫度整數部分  
  153.           temperature_decimal=recieve_data();   //采集溫度小數部分  
  154.           check=recieve_data();                 //采集校驗位  
  155.             
  156.           DHTIO=1;  //采集數據后主機拉高電平  
  157.      }  
  158. }  







  159. void write_com(unsigned char com)   //將模式設置指令或顯示地址寫入液晶模塊
  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)//將數據(字符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)   //將數據寫入液晶模塊
  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;//選擇為定時器0模式,工作方式1,僅用TR0打開啟動。
  253.         TH0=(65536-10000)%256;
  254.         TL0=(65536-10000)/256; //定時10ms        
  255.         ET0=1;//打開定時器0中斷允許
  256.         EA=1;//打開總中斷
  257.         TR0=1;//打開定時器       
  258.                
  259. }

  260. void main()           //主函數
  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. /*****定時器0中斷服務程序****/
  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  //延時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;   //先關閉定時器0
  300.      EA = 0;
  301.           
  302. LED=0;
  303. }  
  304.          
復制代碼


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


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

使用道具 舉報

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

使用道具 舉報

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

哥能發我一分嗎
回復

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

8#
ID:250245 發表于 2020-5-9 13:35 | 只看該作者
應該是AD轉換是需要時間的,AD轉換放在定時器里面,導致你while循環的延時函數不準,DHT11無法滿足時序,可以將AD循環放在主函數,定時器里面計數,當到達0.28ms的時候AD轉換,然后在檢測DHT11,檢測完以后繼續等待下一個0.28ms
回復

使用道具 舉報

9#
ID:250245 發表于 2020-5-9 13:36 | 只看該作者
而且你定時器里還有一個280us的延時,這個遠遠操過了DHT11的30和20us的延時
回復

使用道具 舉報

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 五月天综合网 | 神马九九 | 欧美精品 在线观看 | 国产午夜精品视频 | 亚洲精品日韩综合观看成人91 | 欧美一级大片 | 日韩网站免费观看 | 国产一区二区久久 | 久久精品国产一区二区三区不卡 | 九色在线视频 | 免费观看黄网站 | 欧美精品一区二区三区四区五区 | 欧美在线视频观看 | 国产成年人小视频 | 午夜视频在线视频 | 亚洲一区二区三区观看 | 中日韩欧美一级片 | 国产一级片av | 精品无码久久久久久国产 | 色久五月| 国产成人精品久久二区二区91 | 99精品一区二区三区 | 无码日韩精品一区二区免费 | 亚洲精品久久久久久一区二区 | 国产视频导航 | 久久综合亚洲 | 久久国产精品视频 | 国产一区二区三区久久久久久久久 | 日韩中文字幕高清 | 91资源在线| 国产精品久久久久久久7电影 | 香蕉久久久 | 亚洲国产精品91 | 欧美日韩综合 | 亚洲综合大片69999 | 久久99久久99 | 99国产精品久久久久老师 | 精品视频一区二区在线观看 | 婷婷在线视频 | 狠狠天天| 九九热这里 |