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

標題: 單片機+GP2Y1014AU pm2.5測量+DHT11溫濕度仿真設計源碼 [打印本頁]

作者: yc123    時間: 2018-4-6 09:52
標題: 單片機+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)



作者: abcarry    時間: 2018-5-17 15:09
你AD值都沒傳出來,K=adc0832()  K要么是0 要么是1;
作者: danpianji愛好    時間: 2018-5-17 18:03
abcarry 發表于 2018-5-17 15:09
你AD值都沒傳出來,K=adc0832()  K要么是0 要么是1;

哥能發我一分嗎
作者: c山水    時間: 2019-3-11 09:14
感謝樓主分享
作者: zhzzz    時間: 2019-3-19 07:45
感謝樓主分享,有電路連接圖嗎?
作者: 正在輸入dnf    時間: 2019-4-27 19:51
仿真圖里沒有dht11和pm2.5的傳感器嗎
作者: 大滑稽    時間: 2019-5-19 20:59
解決了嗎兄弟,我的pm怎么一直不顯示,能把新的發我一份哦啊,13122319913@163.com,謝謝
作者: wangxianlong    時間: 2020-5-9 13:35
應該是AD轉換是需要時間的,AD轉換放在定時器里面,導致你while循環的延時函數不準,DHT11無法滿足時序,可以將AD循環放在主函數,定時器里面計數,當到達0.28ms的時候AD轉換,然后在檢測DHT11,檢測完以后繼續等待下一個0.28ms
作者: wangxianlong    時間: 2020-5-9 13:36
而且你定時器里還有一個280us的延時,這個遠遠操過了DHT11的30和20us的延時
作者: Brussino    時間: 2024-3-11 13:59
請問你解決了嘛,我做pm2.5檢測,傳感器輸出電壓太低,沒有任何顯示




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 日本一二三区在线观看 | 国产高清免费视频 | 亚洲成年影院 | 免费视频一区二区 | 一区二区三区在线播放视频 | 最新黄色在线观看 | 黄视频在线网站 | 盗摄精品av一区二区三区 | 久国产| 国产日韩欧美在线 | 亚洲精品久久久一区二区三区 | 国产综合视频 | 精品国产一区二区三区久久影院 | 国产精品久久久久久婷婷天堂 | 国产精品久久久久久久久免费高清 | 美女黄视频网站 | 欧美激情亚洲 | 中文字幕福利视频 | 91porn在线观看| 精品国产乱码久久久久久蜜臀 | 99久久精品国产一区二区三区 | 99久久视频 | 天天综合国产 | 国产69久久精品成人看动漫 | 日韩欧美国产精品 | 亚洲免费网 | 日韩在线视频一区二区三区 | 久久久涩 | 亚洲夜射 | 99精品网| 国产精品一区二区三区久久 | 日韩欧美在线观看 | 日韩精品一区在线观看 | 欧美国产日本一区 | 一级久久久久久 | 天天在线操 | 亚洲国产中文字幕 | www国产成人免费观看视频,深夜成人网 | 综合久久av | 干干干操操操 | 51ⅴ精品国产91久久久久久 |