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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

[原創]自己編的DHT11驅動程序~

  [復制鏈接]
跳轉到指定樓層
樓主
本帖最后由 王朗的誘惑 于 2015-8-4 21:05 編輯

前幾天在某寶上看到DHT11,感覺藍色的外殼做的很漂亮,然后就買了1個。結果發現網上的程序都是給舊12T單片機用的,注釋也沒幾句,用著很不順手。所以就自己按照數據手冊編了驅動程序。還是自己的程序用著順手~~~~拿來和大家分享~~~~
  1. /*********************************************************************************************
  2. 程序名:    DHT11驅動程序
  3. 編寫人:    王朗的誘惑
  4. 編寫時間:  2015年8月4日
  5. 硬件支持:  STC12C5A60S2  DHT11
  6. 接口說明:  DHT11:VCC GND DATA
  7. *********************************************************************************************
  8. 說明:1、單片機是STC12C5A60S2,晶振頻率12MHz,實驗成功。換用12T單片機或別的晶振的時候要修改
  9.           延時函數和JUDGE。程序里判斷超時的變量t的閥值也要改。
  10.           2、好東西要共享,大家隨意折騰~~
  11. *********************************************************************************************/
  12. #include <STC12C5A60S2.H>

  13. typedef unsigned char        uchar;
  14. typedef unsigned int        uint;

  15. #define JUDGE        30                //用于判斷通信的0和1,與單片機速度和晶振頻率有關

  16. sbit DATA = P1^0;                //定義數據引腳

  17. uchar dat_r[5];                        //用于存放從DHT11讀取到的數值

  18. /*********************************************************************************************
  19. 函數名:延時函數
  20. 調  用:Delay30us();/Delay20ms();/Delay1s();
  21. 參  數:無
  22. 返回值:無
  23. 結  果:延時相應時間
  24. 備  注:振蕩晶體為12MHz(所有延時函數Copy自STC-ISP(v6.85).exe)
  25. **********************************************************************************************/
  26. void Delay30us()                //@12.000MHz
  27. {
  28.         unsigned char i;

  29.         i = 87;
  30.         while (--i);
  31. }


  32. void Delay20ms()                //@12.000MHz
  33. {
  34.         unsigned char i, j, k;

  35.         i = 1;
  36.         j = 234;
  37.         k = 113;
  38.         do
  39.         {
  40.                 do
  41.                 {
  42.                         while (--k);
  43.                 } while (--j);
  44.         } while (--i);
  45. }

  46. void Delay1s()                //@12.000MHz
  47. {
  48.         unsigned char i, j, k;

  49.         i = 46;
  50.         j = 153;
  51.         k = 245;
  52.         do
  53.         {
  54.                 do
  55.                 {
  56.                         while (--k);
  57.                 } while (--j);
  58.         } while (--i);
  59. }

  60. /*********************************************************************************************
  61. 函數名:UART串口初始化函數
  62. 調  用:UART_Init();
  63. 參  數:無
  64. 返回值:無
  65. 結  果:啟動UART串口接收中斷,允許串口接收,啟動T/C1產生波特率(占用)
  66. 備  注:振蕩晶體為12MHz,PC串口端設置 [ 4800,8,無,1,無 ]
  67. **********************************************************************************************/
  68. void UART_Init (void){
  69.         EA = 1; //允許總中斷(如不使用中斷,可用//屏蔽)
  70.         ES = 1; //允許UART串口的中斷

  71.         TMOD = 0x20;        //定時器T/C1工作方式2
  72.         SCON = 0x50;        //串口工作方式1,允許串口接收(SCON = 0x40 時禁止串口接收)
  73.         TH1 = 0xF3;        //定時器初值高8位設置
  74.         TL1 = 0xF3;        //定時器初值低8位設置
  75.         PCON = 0x80;        //波特率倍頻(屏蔽本句波特率為2400)
  76.         TR1 = 1;        //定時器啟動   
  77. }

  78. /*********************************************************************************************
  79. 函數名:UART串口發送函數
  80. 調  用:UART_T (?);
  81. 參  數:需要UART串口發送的數據(8位/1字節)
  82. 返回值:無
  83. 結  果:將參數中的數據發送給UART串口,確認發送完成后退出
  84. 備  注:
  85. **********************************************************************************************/
  86. void UART_T (uchar UART_data){ //定義串口發送數據變量
  87.         SBUF = UART_data;        //將接收的數據發送回去
  88.         while(TI == 0);                //檢查發送中斷標志位
  89.         TI = 0;                        //令發送中斷標志位為0(軟件清零)
  90. }

  91. /*********************************************************************************************
  92. 函數名:DHT11讀數據函數
  93. 調  用:? = GetData();
  94. 參  數:無
  95. 返回值:失敗->-1,-2,-3,-4;成功->0
  96. 結  果:讀DHT11數據并保存到數組dat_r[]
  97. 備  注:
  98. **********************************************************************************************/
  99. char GetData (void)
  100. {
  101.         uchar i,j;                                //for循環變量
  102.         uchar t;                                //超時判斷
  103.         uchar dat8=0;                        //一次讀取的8位數據,需要讀5次

  104.         DATA = 0;                                //主機發起始信號
  105.         Delay20ms();                        //主機拉低總線至少18ms
  106.         DATA = 1;                                //主機拉高總線20~40us
  107.         Delay30us();

  108.         t = 80;                                        //設置超時等待時間
  109.         while(DATA && t--);                //等待DHT11拉低總線
  110.         if(t == 0)                                //超時
  111.         {
  112.                 DATA = 1;
  113.                 return -1;                        //通信錯誤退出,返回錯誤信號:-1
  114.         }

  115.         //等80us響應信號
  116.         t = 250;                                //設置超時等待時間
  117.         while(!DATA && t--);        //等待DHT11拉高總線
  118.         if(t == 0)                                //超時
  119.         {
  120.                 DATA = 1;
  121.                 return -2;                        //通信錯誤退出,返回錯誤信號:-2
  122.         }

  123.         //等80us響應信號
  124.         t = 250;                                //設置超時等待時間
  125.         while(DATA && t--);                //等待DHT11拉低總線
  126.         if(t == 0)                                //超時
  127.         {
  128.                 DATA = 1;
  129.                 return -3;                        //通信錯誤退出,返回錯誤信號:-3
  130.         }

  131.         for(j=0; j<5; j++)                //5次讀取
  132.         {
  133.                 for(i=0; i<8; i++)                        //1次8個位
  134.                 {
  135.                         //等待50us開始時隙
  136.                         t = 150;                                //設置超時等待時間
  137.                         while(!DATA && t--);        //等待DHT11拉高總線
  138.                         if(t == 0)                                //超時
  139.                         {
  140.                                 DATA = 1;
  141.                                 return -4;                        //通信錯誤退出,返回錯誤信號:-4
  142.                         }
  143.                         t = 0;                                        //記錄時間清零
  144.                         while(DATA && ++t);                //等待并記錄高電平持續時間
  145.                         dat8 <<= 1;
  146.                         if(t > JUDGE)                        //高電平持續時間較長(70us)
  147.                                 dat8 += 1;                        //傳輸值為1
  148.                         //else dat8 += 0;
  149.                 }
  150.                 dat_r[j] = dat8;
  151.         }

  152.         Delay30us();                //等待DHT11拉低50us
  153.         Delay30us();
  154.         DATA = 1;                        //結束,拉高總線
  155.         return 0;                        //返回成功信號
  156. }

  157. /*********************************************************************************************
  158. 函數名:數據校驗函數
  159. 調  用:? = Check();
  160. 參  數:無
  161. 返回值:成功->0;失敗->-1;
  162. 結  果:數據校驗
  163. 備  注:數據傳送正確時校驗和數據等于“8bit濕度整數數據+8bit濕度小數數據+8bi溫度整數數據+8bit溫度小數數據”所得結果的末8位。
  164. **********************************************************************************************/
  165. char Check (void)
  166. {
  167.         uchar i;                        //for循環變量
  168.         uint chk=0;                        //校驗和
  169.         for(i=0; i<4; i++)
  170.                 chk += dat_r[i];                //累加
  171.         if((uchar)chk != dat_r[4])        //比對
  172.                 return -1;                                //返回錯誤信號:-1
  173.         else
  174.                 return 0;                                //返回正確信號:0
  175. }

  176. /*********************************************************************************************
  177. 函數名:主函數
  178. 調  用:無
  179. 參  數:無
  180. 返回值:無
  181. 結  果:讀DHT11數據并送到串口顯示
  182. 備  注:
  183. **********************************************************************************************/
  184. void main (void)
  185. {
  186.         char i;
  187.         UART_Init();                //串口初始化
  188.         Delay1s();                        //等待DHT11穩定
  189.         do
  190.         {
  191.                 i = GetData();        //讀數據
  192.                 if(i != 0)                //有錯誤
  193.                 {
  194.                         UART_T(-i);        //返回錯誤值
  195.                         break;                //重新開始
  196.                 }

  197.                 i = Check();        //數據校驗
  198.                 if(i != 0)                //有錯誤
  199.                 {
  200.                         UART_T(-i);        //返回錯誤值
  201.                         break;                //重新開始
  202.                 }

  203.                 UART_T(dat_r[0]);                //濕度整數
  204.                 //UART_T(dat_r[1]);                //濕度小數(根據數據手冊,DHT11小數部分一直是0沒用)
  205.                 UART_T(dat_r[2]);                //溫度整數
  206.                 //UART_T(dat_r[3]);                //溫度小數(根據數據手冊,DHT11小數部分一直是0沒用)
  207.                 UART_T(dat_r[4]);                //校驗值

  208.                 Delay1s();                                //經測試,兩次連讀要至少延時80ms        
  209.         }while(1);
  210. }//main
復制代碼



評分

參與人數 1黑幣 +35 收起 理由
davg1 + 35 贊一個!程序寫的很工整

查看全部評分

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

使用道具 舉報

來自 2#
ID:84652 發表于 2018-9-16 11:16 | 只看該作者
把主函數里的break都改成continue
回復

使用道具 舉報

來自 3#
ID:84652 發表于 2019-3-1 21:22 | 只看該作者
修改一處bug:請把程序里所有的t--改成--t,否則錯誤值返回不了。原來的程序一次成功了,所以直到現在才發現這個bug……向大家道歉……

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

地板
ID:123712 發表于 2016-12-28 22:03 | 只看該作者
謝謝樓主分享資料,學習中
回復

使用道具 舉報

5#
ID:158563 發表于 2016-12-29 10:43 | 只看該作者
感覺好難……
回復

使用道具 舉報

6#
ID:146045 發表于 2017-3-18 11:45 | 只看該作者
程序很好
回復

使用道具 舉報

7#
ID:186776 發表于 2017-5-17 21:02 | 只看該作者
學習了
回復

使用道具 舉報

8#
ID:186776 發表于 2017-5-17 21:26 來自手機 | 只看該作者
學習了
回復

使用道具 舉報

9#
ID:145935 發表于 2017-5-18 10:41 | 只看該作者
感謝分享,學習了。
回復

使用道具 舉報

10#
ID:141361 發表于 2017-5-25 13:13 | 只看該作者
這兩天一直在研究,開始初始化都失敗,然后呢卻卻讀出來數據,真是鬧心,借鑒一下程序看有沒有效果
回復

使用道具 舉報

11#
ID:202299 發表于 2017-5-26 11:06 | 只看該作者
請問大神,有沒有DHT11加1602顯示的綜合程序?
回復

使用道具 舉報

12#
ID:202299 發表于 2017-5-26 11:06 | 只看該作者
請問大神,要用1602顯示的話,還要用到串口嗎?
回復

使用道具 舉報

13#
ID:84652 發表于 2017-8-21 14:43 | 只看該作者
smallriver 發表于 2017-5-25 13:13
這兩天一直在研究,開始初始化都失敗,然后呢卻卻讀出來數據,真是鬧心,借鑒一下程序看有沒有效果

單總線一般都是時序問題,最好是能有臺示波器看看。
回復

使用道具 舉報

14#
ID:84652 發表于 2017-8-21 14:44 | 只看該作者
aiait 發表于 2017-5-26 11:06
請問大神,要用1602顯示的話,還要用到串口嗎?

把數據送到1602屏幕上就行了吧?只是這樣的話不用串口。串口可以用來調試,看看有沒有數據讀出來。
回復

使用道具 舉報

15#
ID:229113 發表于 2017-8-24 13:41 | 只看該作者
我在stc15上用的,仿真軟件上串口輸出時十六進制,怎么才能輸出的是十進制呢?
回復

使用道具 舉報

16#
ID:84652 發表于 2017-8-25 11:02 | 只看該作者
cp66 發表于 2017-8-24 13:41
我在stc15上用的,仿真軟件上串口輸出時十六進制,怎么才能輸出的是十進制呢?

寫個發送字符串函數,把數據的十位和個位分開發,串口助手用文本模式接收。
回復

使用道具 舉報

17#
ID:215834 發表于 2017-11-18 09:55 | 只看該作者
樓主好,感謝分享。請問為什么要檢測那么多次錯誤呢。另外 &nbsp;while(DATA && ++t);&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 語句檢測時間t自加一次需要多久時間,謝謝樓主
回復

使用道具 舉報

18#
ID:84652 發表于 2017-11-18 10:40 | 只看該作者
本帖最后由 王朗的誘惑 于 2017-11-18 11:03 編輯
njzyg 發表于 2017-11-18 09:55
樓主好,感謝分享。請問為什么要檢測那么多次錯誤呢。另外  while(DATA && ++t);      ...

DHT11是單總線器件,驅動的時候時序容易出問題,但是環節太多不知道問題出在哪,調試的時候就費勁。不斷檢測錯誤就是想知道問題出在哪個環節,然后有針對性地解決。那個自加的具體時間不知道,和單片機速度有關系,先把前面調試好了,然后記錄下來0和1對應的t值通過串口發上來,取平均值就可以了。
回復

使用道具 舉報

19#
ID:326995 發表于 2018-5-10 20:55 | 只看該作者
代碼很有用
回復

使用道具 舉報

20#
ID:95072 發表于 2018-11-10 16:49 | 只看該作者
值得學習!!!
回復

使用道具 舉報

21#
ID:458168 發表于 2019-1-8 23:12 | 只看該作者
謝謝樓主
回復

使用道具 舉報

22#
ID:445069 發表于 2019-3-1 17:29 | 只看該作者
樓主,有沒有在STC89C52上測試過DHT11?
找了很多網上的代碼,根本就讀不出來。
回復

使用道具 舉報

23#
ID:84652 發表于 2019-3-1 19:39 | 只看該作者
ontheroad 發表于 2019-3-1 17:29
樓主,有沒有在STC89C52上測試過DHT11?
找了很多網上的代碼,根本就讀不出來。

沒有誒,不過我手上有元件,我可以幫你試試~
回復

使用道具 舉報

24#
ID:84652 發表于 2019-3-1 21:18 | 只看該作者
ontheroad 發表于 2019-3-1 17:29
樓主,有沒有在STC89C52上測試過DHT11?
找了很多網上的代碼,根本就讀不出來。

這是STC89C52RC的程序,晶振頻率11.0592MHz,接口還是P1.0,剛剛測試成功了。

DHT11-STC89.zip

35.33 KB, 下載次數: 80, 下載積分: 黑幣 -5

11.0592MHz

回復

使用道具 舉報

25#
ID:434090 發表于 2019-3-16 11:34 | 只看該作者
最近在研究dht11,多謝分享
回復

使用道具 舉報

26#
ID:448233 發表于 2019-11-12 09:11 | 只看該作者

樓主,有沒有在STC15F408AD測試過DHT11?
找了很多網上的代碼,根本就讀不出來。
回復

使用道具 舉報

27#
ID:84652 發表于 2019-11-19 00:20 | 只看該作者
zeki520kiki 發表于 2019-11-12 09:11
樓主,有沒有在STC15F408AD測試過DHT11?
找了很多網上的代碼,根本就讀不出來。

我沒試過……如果實在調不出來,強烈建議用示波器或者邏輯分析儀看看波形。
回復

使用道具 舉報

28#
ID:627950 發表于 2019-12-15 20:16 | 只看該作者
樓主,有沒有在IAP15W4K58S4測試過DHT11?
求分享~
回復

使用道具 舉報

29#
ID:666819 發表于 2019-12-17 23:32 | 只看該作者
我測試成功了,謝謝樓主的幫助
回復

使用道具 舉報

30#
ID:84652 發表于 2020-1-7 22:09 | 只看該作者
夢在夏天 發表于 2019-12-15 20:16
樓主,有沒有在IAP15W4K58S4測試過DHT11?
求分享~

沒有……盲調主要看人品,最好想辦法搞個示波器或者邏輯分析儀。
回復

使用道具 舉報

31#
ID:259035 發表于 2020-1-31 17:23 | 只看該作者

樓主,有沒有在STC15f2k60s上測試過DHT11?
找了很多網上的代碼,根本就讀不出來。
回復

使用道具 舉報

32#
ID:84652 發表于 2020-2-7 19:30 | 只看該作者
yechuan220 發表于 2020-1-31 17:23
樓主,有沒有在STC15f2k60s上測試過DHT11?
找了很多網上的代碼,根本就讀不出來。

沒……現在我大概明白,提出這些問題的老哥們是沒有示波器什么的,那就串口調試吧。DHT11這東西不是把信號全發過去才返回的,通信的過程就是反饋的過程,比如主機發一個開始信號,然后DHT11就會響應一個低電平信號,檢測這個信號,就知道之前的開始信號正不正常。類似于打電話,得聽到對方的聲音,才知道信號沒問題,對吧。
回復

使用道具 舉報

33#
ID:626079 發表于 2020-3-18 23:14 | 只看該作者
感謝樓主的程序,麻煩咨詢下樓主,你的STC52程序中
#define JUDGE        4                //用于判斷通信的0和1,與單片機速度和晶振頻率有關
這是起啥作用。 我看在程序里調用時:
if(t >JUDGE)                        //高電平持續時間較長(70us)
dat8 += 1;                        //傳輸值為1

能解答一下為什么t>JDGE是與70us進行比較呢?新手不太明白,謝謝了。
還有dat8 += 1;是不是就是把dat8最后一位給“1”的意思哈?
回復

使用道具 舉報

34#
ID:710428 發表于 2020-3-19 20:34 | 只看該作者
謝謝分享
回復

使用道具 舉報

35#
ID:282869 發表于 2020-3-20 13:32 | 只看該作者
值得參考學習,謝謝分享.
回復

使用道具 舉報

36#
ID:84652 發表于 2020-3-20 14:51 | 只看該作者
本帖最后由 王朗的誘惑 于 2020-3-20 19:46 編輯
xmfjfhcel 發表于 2020-3-18 23:14
感謝樓主的程序,麻煩咨詢下樓主,你的STC52程序中
#define JUDGE        4                //用于判斷通 ...

問題1:


看下數據手冊里的圖5,DHT11數據高電平持續時間規定為70us,所以比較這個時間判斷數據是1還是0。JUDGE是手動試出來的,這個值理論上最好能讓單片機計時在DHT11數據高電平的時間中間,就是(70+28)/2 = 49 us。
好好研究下數據手冊是解決問題的最好辦法。已附上數據手冊。

問題2:
是。相當于 dat8 |= 1;

DHT11說明書081206.pdf

677.52 KB, 下載次數: 7, 下載積分: 黑幣 -5

DHT11數據手冊

回復

使用道具 舉報

37#
ID:626079 發表于 2020-3-20 16:43 | 只看該作者


謝謝大俠, 高手。已經用你的程序做出來通過……
http://www.zg4o1577.cn/bbs/dpj-182291-1.html
回復

使用道具 舉報

38#
ID:246783 發表于 2020-3-21 19:56 | 只看該作者
你這個思路比較好   相當于軟件示波器了       借鑒你這個思路調了408AS 的dht11   數據出來了 !!

另外問個問題  :  串口接收時      開文本接收時 數據一直是字符亂碼  怎么解決 ?

                  SendString("\r\n濕度:");
                        SendData(dat_r[0]);                //濕度整數        
             
                SendString("\r\n溫度:");
                SendData(dat_r[2]);                //溫度整數                


/////////////////////////////////////////
我的串口函數  :  
/******************************************************************************

****************************************************************Author:Liming**/
void SendData(unsigned char dat)
{
    while (B_TX1_Busy);               //等待前面的數據發送完成
    B_TX1_Busy = 1;
    SBUF = dat;                 //寫數據到UART數據寄存器
}

/*******************************************************************************
  * @brief  None
  * @param  None
  * @retval None
****************************************************************Author:Liming**/
void SendString(char *s)
{
    while (*s)                  //檢測字符串結束標志
    {
        SendData(*s++);         //發送當前字符
    }
}
回復

使用道具 舉報

39#
ID:84652 發表于 2020-3-22 13:13 | 只看該作者
sasafair 發表于 2020-3-21 19:56
你這個思路比較好   相當于軟件示波器了       借鑒你這個思路調了408AS 的dht11   數據出來了 !!

另外 ...

文本接收時發送的數字需要進行ASCII編碼,比如發送0,實際發送的字節是0x30;發送1,實際發送的字節是0x31,依次類推。
實現的方法有很多,可以自己寫轉換函數,轉換要發送的數據的每個十進制位;也可以用sprintf函數把數據轉換成字符串然后發送字符串;還可以重定向printf然后直接用printf。
你這個情況的話,推薦使用sprintf。如果為了學習ASCII編碼,建議自己寫個轉換函數。
祝好運~
回復

使用道具 舉報

40#
ID:733775 發表于 2020-4-20 23:25 | 只看該作者
用LCD顯示的數據特別不準咋辦。。是這東西本來就誤差大,還是時間沒取好導致數據有誤差啊?或者算法?不能直接高位/10,%10?太離譜了家里溫度顯示27攝氏度,天氣預報也就15攝氏度
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91久久精品日日躁夜夜躁欧美 | 欧美中文字幕一区二区三区 | 国产精品久久久久久久久久免费看 | 中文字幕在线一区 | 青青草原综合久久大伊人精品 | 久久综合久久综合久久 | 国产精品毛片一区二区三区 | 久久亚洲国产精品日日av夜夜 | 日本成人免费网站 | 欧美v免费 | 一区二区三区av | 欧美极品在线观看 | 精品国模一区二区三区欧美 | www网站在线观看 | 精品国产91久久久久久 | 久久久成人一区二区免费影院 | 国产成人在线播放 | 亚洲小视频 | 一片毛片| 成人在线看片 | 国产免费一区二区三区免费视频 | 午夜精品久久久久久久星辰影院 | 国产一区二区三区在线看 | 国产精品美女久久久久aⅴ国产馆 | 一区二区三区四区免费在线观看 | 亚洲国产日韩欧美 | 91人人在线 | a看片| 国产一区二区三区视频 | 成人区精品一区二区婷婷 | 自拍亚洲 | 中文字幕在线视频免费观看 | 成年人在线播放 | 国产精品视频网址 | 久久久久久国模大尺度人体 | 国产精品久久国产精品 | 国产亚洲精品久久yy50 | 午夜欧美一区二区三区在线播放 | 亚洲国产成人精品女人久久久野战 | 欧美一区二区免费 | 国产精品视频999 |