找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2443|回復(fù): 3
收起左側(cè)

關(guān)于使用51單片機(jī)驅(qū)動(dòng)DHT11仿真成功而實(shí)物不成的問(wèn)題

[復(fù)制鏈接]
回帖獎(jiǎng)勵(lì) 5 黑幣 回復(fù)本帖可獲得 1 黑幣獎(jiǎng)勵(lì)! 每人限 1 次
ID:894722 發(fā)表于 2021-5-17 21:18 | 顯示全部樓層 |閱讀模式
5.png
這是仿真圖,是可以使用的。

但是在程序中,它好像卡在了讀取DHT11的數(shù)據(jù)當(dāng)中, Void ReadDhtData();中 ,想讓大神們看看這個(gè)函數(shù)有沒(méi)有問(wèn)題,以及如何改錯(cuò)


// 讀取DHT11的一幀數(shù)據(jù),濕高、濕低(0)、溫高、溫低(0)、校驗(yàn)碼
  1. void ReadDhtData()
  2. {            
  3.         uchar HumiHig;                // 濕度高檢測(cè)值
  4.         uchar HumiLow;                // 濕度低檢測(cè)值
  5.         uchar TemHig;                        // 溫度高檢測(cè)值
  6.         uchar TemLow;                        // 溫度低檢測(cè)值
  7.         uchar check;                        // 校驗(yàn)字節(jié)
  8.         
  9.         
  10.         DHT11_P=1;        //拉高等待     
  11.         DelayMs(20);
  12.         
  13.         
  14.         
  15.         
  16.         
  17.         DHT11_P=0;                                // 主機(jī)拉低
  18.         DelayMs(20);                        // 保持20毫秒
  19.         
  20.         DHT11_P=1;                                // DATA總線由上拉電阻拉高  準(zhǔn)備輸出

  21.         Delay10us();                         // 延時(shí)等待30us
  22.         Delay10us();
  23.         Delay10us();

  24.         while(!DHT11_P);        // 等待DHT的低電平結(jié)束
  25.         while(DHT11_P);                // 等待DHT的高電平結(jié)束

  26.         //進(jìn)入數(shù)據(jù)接收狀態(tài)
  27.         HumiHig = DhtReadByte();         // 濕度高8位
  28.         HumiLow = DhtReadByte();         // 濕度低8為,總為0
  29.         TemHig  = DhtReadByte();         // 溫度高8位
  30.         TemLow  = DhtReadByte();         // 溫度低8為,總為0
  31.         check   = DhtReadByte();        // 8位校驗(yàn)碼,其值等于讀出的四個(gè)字節(jié)相加之和的低8位

  32.         DHT11_P=1;                                // 拉高總線

  33.         if(check==HumiHig + HumiLow + TemHig + TemLow)                 // 如果收到的數(shù)據(jù)無(wú)誤
  34.         {
  35.                 temp=TemHig;                         // 將溫度的檢測(cè)結(jié)果賦值給全局變量temp
  36.                 humi=HumiHig;                        // 將濕度的檢測(cè)結(jié)果賦值給全局變量humi
  37.         }
  38. }




  39. 下面是程序源碼
  40. #include <reg52.h>                                   // 頭文件包含
  41. #include <intrins.h>

  42. #define uchar unsigned char
  43. #define uint  unsigned int              

  44. sfr ISP_DATA  = 0xe2;                        // 數(shù)據(jù)寄存器
  45. sfr ISP_ADDRH = 0xe3;                        // 地址寄存器高八位
  46. sfr ISP_ADDRL = 0xe4;                        // 地址寄存器低八位
  47. sfr ISP_CMD   = 0xe5;                        // 命令寄存器
  48. sfr ISP_TRIG  = 0xe6;                        // 命令觸發(fā)寄存器
  49. sfr ISP_CONTR = 0xe7;                        // 命令寄存器

  50. sbit Buzzer_P  = P1^4;    // 蜂鳴器
  51. sbit DHT11_P   = P1^5;                 // 溫濕度傳感器DHT11數(shù)據(jù)接入
  52. sbit LcdRs_P   = P1^0;    // 1602液晶的RS管腳      
  53. sbit LcdRw_P   = P1^1;    // 1602液晶的RW管腳
  54. sbit LcdEn_P   = P1^2;    // 1602液晶的EN管腳
  55. sbit KeySet_P  = P3^5;                // “設(shè)置”按鍵的管腳
  56. sbit KeyDown_P = P3^6;                // “減”按鍵的管腳
  57. sbit KeyUp_P   = P3^7;                // “加”按鍵的管腳
  58. sbit LedTL_P   = P2^0;                // 溫度過(guò)低報(bào)警指示燈
  59. sbit LedTH_P   = P2^1;                // 溫度過(guò)高報(bào)警指示燈
  60. sbit LedHL_P   = P2^2;                // 濕度過(guò)低報(bào)警指示燈
  61. sbit LedHH_P   = P2^3;                // 濕度過(guò)高報(bào)警指示燈

  62. uchar temp;                                        // 保存溫度
  63. uchar humi;                                        // 保存濕度

  64. uchar AlarmTL;                        // 溫度下限報(bào)警值
  65. uchar AlarmTH;                        // 溫度上限報(bào)警值
  66. uchar AlarmHL;                        // 濕度下限報(bào)警值
  67. uchar AlarmHH;                        // 濕度上限報(bào)警值



  68. /*********************************************************/
  69. // 單片機(jī)內(nèi)部EEPROM不使能
  70. /*********************************************************/
  71. void ISP_Disable()
  72. {
  73.         ISP_CONTR = 0;
  74.         ISP_ADDRH = 0;
  75.         ISP_ADDRL = 0;
  76. }


  77. /*********************************************************/
  78. // 從單片機(jī)內(nèi)部EEPROM讀一個(gè)字節(jié),從0x2000地址開(kāi)始
  79. /*********************************************************/
  80. unsigned char EEPROM_Read(unsigned int add)
  81. {
  82.         ISP_DATA  = 0x00;
  83.         ISP_CONTR = 0x83;
  84.         ISP_CMD   = 0x01;
  85.         ISP_ADDRH = (unsigned char)(add>>8);
  86.         ISP_ADDRL = (unsigned char)(add&0xff);
  87.         // 對(duì)STC89C51系列來(lái)說(shuō),每次要寫入0x46,再寫入0xB9,ISP/IAP才會(huì)生效
  88.         ISP_TRIG  = 0x46;           
  89.         ISP_TRIG  = 0xB9;
  90.         _nop_();
  91.         ISP_Disable();
  92.         return (ISP_DATA);
  93. }


  94. /*********************************************************/
  95. // 往單片機(jī)內(nèi)部EEPROM寫一個(gè)字節(jié),從0x2000地址開(kāi)始
  96. /*********************************************************/
  97. void EEPROM_Write(unsigned int add,unsigned char ch)
  98. {
  99.         ISP_CONTR = 0x83;
  100.         ISP_CMD   = 0x02;
  101.         ISP_ADDRH = (unsigned char)(add>>8);
  102.         ISP_ADDRL = (unsigned char)(add&0xff);
  103.         ISP_DATA  = ch;
  104.         ISP_TRIG  = 0x46;
  105.         ISP_TRIG  = 0xB9;
  106.         _nop_();
  107.         ISP_Disable();
  108. }


  109. /*********************************************************/
  110. // 擦除單片機(jī)內(nèi)部EEPROM的一個(gè)扇區(qū)
  111. // 寫8個(gè)扇區(qū)中隨便一個(gè)的地址,便擦除該扇區(qū),寫入前要先擦除
  112. /*********************************************************/
  113. void Sector_Erase(unsigned int add)         
  114. {
  115.         ISP_CONTR = 0x83;
  116.         ISP_CMD   = 0x03;
  117.         ISP_ADDRH = (unsigned char)(add>>8);
  118.         ISP_ADDRL = (unsigned char)(add&0xff);
  119.         ISP_TRIG  = 0x46;
  120.         ISP_TRIG  = 0xB9;
  121.         _nop_();
  122.         ISP_Disable();
  123. }


  124. /*********************************************************/
  125. // 毫秒級(jí)的延時(shí)函數(shù),time是要延時(shí)的毫秒數(shù)
  126. /*********************************************************/
  127. void DelayMs(uint time)
  128. {
  129.         uint i,j;
  130.         for(i=0;i<time;i++)
  131.                 for(j=0;j<112;j++);
  132. }


  133. /*********************************************************/
  134. // 1602液晶寫命令函數(shù),cmd就是要寫入的命令
  135. /*********************************************************/
  136. void LcdWriteCmd(uchar cmd)
  137. {
  138.         LcdRs_P = 0;
  139.         LcdRw_P = 0;
  140.         LcdEn_P = 0;
  141.         P0=cmd;
  142.         DelayMs(2);
  143.         LcdEn_P = 1;   
  144.         DelayMs(2);
  145.         LcdEn_P = 0;        
  146. }


  147. /*********************************************************/
  148. // 1602液晶寫數(shù)據(jù)函數(shù),dat就是要寫入的數(shù)據(jù)
  149. /*********************************************************/
  150. void LcdWriteData(uchar dat)
  151. {
  152.         LcdRs_P = 1;
  153.         LcdRw_P = 0;
  154.         LcdEn_P = 0;
  155.         P0=dat;
  156.         DelayMs(2);
  157.         LcdEn_P = 1;   
  158.         DelayMs(2);
  159.         LcdEn_P = 0;
  160. }


  161. /*********************************************************/
  162. // 1602液晶初始化函數(shù)
  163. /*********************************************************/
  164. void LcdInit()
  165. {
  166.         LcdWriteCmd(0x38);        // 16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)口
  167.         LcdWriteCmd(0x0C);        // 開(kāi)顯示,不顯示光標(biāo)
  168.         LcdWriteCmd(0x06);        // 地址加1,當(dāng)寫入數(shù)據(jù)后光標(biāo)右移
  169.         LcdWriteCmd(0x01);        // 清屏
  170. }


  171. /*********************************************************/
  172. // 液晶光標(biāo)定位函數(shù)
  173. /*********************************************************/
  174. void LcdGotoXY(uchar line,uchar column)
  175. {
  176.         // 第一行
  177.         if(line==0)        
  178.                 LcdWriteCmd(0x80+column);
  179.         // 第二行
  180.         if(line==1)        
  181.                 LcdWriteCmd(0x80+0x40+column);
  182. }


  183. /*********************************************************/
  184. // 液晶輸出字符串函數(shù)
  185. /*********************************************************/
  186. void LcdPrintStr(uchar *str)
  187. {
  188.         while(*str!='\0')                         // 判斷是否到字符串的盡頭了
  189.                 LcdWriteData(*str++);
  190. }


  191. /*********************************************************/
  192. // 液晶輸出數(shù)字
  193. /*********************************************************/
  194. void LcdPrintNum(uchar num)
  195. {
  196.         LcdWriteData(num/10+48);        // 十位
  197.         LcdWriteData(num%10+48);         // 個(gè)位
  198. }


  199. /*********************************************************/
  200. // 液晶顯示內(nèi)容的初始化
  201. /*********************************************************/
  202. void LcdShowInit()
  203. {
  204.         LcdGotoXY(0,0);                                                                // 第0行的顯示內(nèi)容
  205.         LcdPrintStr("  DHT11 System  ");
  206.         LcdGotoXY(1,0);                                                           // 第1行的顯示內(nèi)容
  207.         LcdPrintStr("T:   C   H:   %");
  208.         LcdGotoXY(1,4);                                                                // 溫度單位攝氏度上面的圓圈符號(hào)
  209.         LcdWriteData(0xdf);        
  210. }




  211. void Delay10us()
  212. {
  213.         _nop_();             // 執(zhí)行一條指令,延時(shí)1微秒
  214.         _nop_();
  215.         _nop_();
  216.         _nop_();
  217.         _nop_();
  218.         _nop_();
  219.         _nop_();
  220.         _nop_();
  221.         _nop_();
  222.         _nop_();
  223. }



  224. // 讀取DHT11單總線上的一個(gè)字節(jié)

  225. uchar DhtReadByte(void)
  226. {
  227.         bit bit_i;
  228.         uchar j;
  229.         uchar dat=0;

  230.         for(j=0;j<8;j++)   
  231.         {
  232.                 while(!DHT11_P);        // 等待低電平結(jié)束        
  233.                 Delay10us();                        // 延時(shí)
  234.                 Delay10us();
  235.                 Delay10us();
  236.                 if(DHT11_P==1)                // 判斷數(shù)據(jù)線是高電平還是低電平
  237.                 {
  238.                         bit_i=1;
  239.                         while(DHT11_P);
  240.                 }
  241.                 else
  242.                 {
  243.                         bit_i=0;
  244.                 }
  245.                 dat<<=1;                                   // 將該位移位保存到dat變量中
  246.                 dat|=bit_i;   
  247.         }
  248.         return(dat);  
  249. }



  250. // 讀取DHT11的一幀數(shù)據(jù),濕高、濕低(0)、溫高、溫低(0)、校驗(yàn)碼
  251. void ReadDhtData()
  252. {            
  253.         uchar HumiHig;                // 濕度高檢測(cè)值
  254.         uchar HumiLow;                // 濕度低檢測(cè)值
  255.         uchar TemHig;                        // 溫度高檢測(cè)值
  256.         uchar TemLow;                        // 溫度低檢測(cè)值
  257.         uchar check;                        // 校驗(yàn)字節(jié)
  258.         
  259.         
  260.         DHT11_P=1;        //拉高等待     
  261.         DelayMs(20);
  262.         
  263.         
  264.         
  265.         
  266.         
  267.         DHT11_P=0;                                // 主機(jī)拉低
  268.         DelayMs(20);                        // 保持20毫秒
  269.         
  270.         DHT11_P=1;                                // DATA總線由上拉電阻拉高  準(zhǔn)備輸出

  271.         Delay10us();                         // 延時(shí)等待30us
  272.         Delay10us();
  273.         Delay10us();

  274.         while(!DHT11_P);        // 等待DHT的低電平結(jié)束
  275.         while(DHT11_P);                // 等待DHT的高電平結(jié)束

  276.         //進(jìn)入數(shù)據(jù)接收狀態(tài)
  277.         HumiHig = DhtReadByte();         // 濕度高8位
  278.         HumiLow = DhtReadByte();         // 濕度低8為,總為0
  279.         TemHig  = DhtReadByte();         // 溫度高8位
  280.         TemLow  = DhtReadByte();         // 溫度低8為,總為0
  281.         check   = DhtReadByte();        // 8位校驗(yàn)碼,其值等于讀出的四個(gè)字節(jié)相加之和的低8位

  282.         DHT11_P=1;                                // 拉高總線

  283.         if(check==HumiHig + HumiLow + TemHig + TemLow)                 // 如果收到的數(shù)據(jù)無(wú)誤
  284.         {
  285.                 temp=TemHig;                         // 將溫度的檢測(cè)結(jié)果賦值給全局變量temp
  286.                 humi=HumiHig;                        // 將濕度的檢測(cè)結(jié)果賦值給全局變量humi
  287.         }
  288. }


  289. /*********************************************************/
  290. // 是否需要報(bào)警判斷
  291. /*********************************************************/
  292. void AlarmJudge(void)
  293. {
  294.         uchar i;

  295.         if(temp>AlarmTH)                                // 溫度是否過(guò)高
  296.         {
  297.                 LedTH_P=0;
  298.                 LedTL_P=1;
  299.         }
  300.         else if(temp<AlarmTL)                // 溫度是否過(guò)低
  301.         {
  302.                 LedTL_P=0;
  303.                 LedTH_P=1;
  304.         }
  305.         else                                                                                // 溫度正常
  306.         {
  307.                 LedTH_P=1;
  308.                 LedTL_P=1;
  309.         }

  310.         if(humi>AlarmHH)                           // 濕度是否過(guò)高
  311.         {
  312.                 LedHH_P=0;
  313.           LedHL_P=1;
  314.         }
  315.         else if(humi<AlarmHL)                // 濕度是否過(guò)低
  316.         {
  317.                 LedHL_P=0;
  318.                 LedHH_P=1;
  319.         }
  320.         else                                                                           // 濕度正常
  321.         {
  322.                 LedHH_P=1;
  323.                 LedHL_P=1;
  324.         }

  325.         if((LedHH_P==0)||(LedHL_P==0)||(LedTH_P==0)||(LedTL_P==0))         // 蜂鳴器判斷,只要至少1個(gè)報(bào)警燈亮,蜂鳴器就報(bào)警
  326.         {
  327.                 for(i=0;i<3;i++)
  328.                 {
  329.                         Buzzer_P=0;
  330.                         DelayMs(100);
  331.                         Buzzer_P=1;
  332.                         DelayMs(100);
  333.                 }
  334.         }
  335. }


  336. /*********************************************************/
  337. // 按鍵掃描,用于設(shè)置溫濕度報(bào)警范圍
  338. /*********************************************************/
  339. void KeyScanf()
  340. {
  341.         if(KeySet_P==0)                // 判斷設(shè)置按鍵是否被按下
  342.         {
  343.                 /*將液晶顯示改為設(shè)置頁(yè)面的*******************************************************/

  344.                 LcdWriteCmd(0x01);                                // 設(shè)置界面的顯示框架
  345.                 LcdGotoXY(0,0);
  346.                 LcdPrintStr("Temp: 20-40");
  347.                 LcdGotoXY(1,0);
  348.                 LcdPrintStr("Humi: 10-30");
  349.                
  350.                 LcdGotoXY(0,6);                                                 // 在液晶上填充溫度的下限值        
  351.                 LcdPrintNum(AlarmTL);        
  352.                 LcdGotoXY(0,9);                                                 // 在液晶上填充溫度的上限值
  353.                 LcdPrintNum(AlarmTH);

  354.                 LcdGotoXY(1,6);                                                 // 在液晶上填充濕度的下限值
  355.                 LcdPrintNum(AlarmHL);        
  356.                 LcdGotoXY(1,9);                                                  // 在液晶上填充濕度的上限值
  357.                 LcdPrintNum(AlarmHH);

  358.                 LcdGotoXY(0,7);                                                 // 光標(biāo)定位到第0行第7列
  359.                 LcdWriteCmd(0x0F);                                // 光標(biāo)閃爍
  360.                
  361.                 DelayMs(10);                                                  // 去除按鍵按下的抖動(dòng)
  362.                 while(!KeySet_P);                                         // 等待按鍵釋放
  363.                 DelayMs(10);                                                  // 去除按鍵松開(kāi)的抖動(dòng)

  364.                 /*設(shè)置溫度的下限值****************************************************************/

  365.                 while(KeySet_P)                                                // “設(shè)置鍵”沒(méi)有被按下,則一直處于溫度下限的設(shè)置
  366.                 {
  367.                         if(KeyDown_P==0)                                // 判斷 “減按鍵“ 是否被按下               
  368.                         {
  369.                                 if(AlarmTL>0)                                        // 只有當(dāng)溫度下限值大于0時(shí),才能減1
  370.                                         AlarmTL--;
  371.                                 LcdGotoXY(0,6);                                 // 重新刷新顯示更改后的溫度下限值        
  372.                                 LcdPrintNum(AlarmTL);                  
  373.                                 LcdGotoXY(0,7);                                // 重新定位閃爍的光標(biāo)位置
  374.                                 DelayMs(350);                                        // 延時(shí)
  375.                         }
  376.                         if(KeyUp_P==0)                                  // 判斷 “加按鍵“ 是否被按下
  377.                         {
  378.                                 if(AlarmTL<99)                          // 只有當(dāng)溫度下限值小于99時(shí),才能加1
  379.                                         AlarmTL++;
  380.                                 LcdGotoXY(0,6);                                  // 重新刷新顯示更改后的溫度下限值
  381.                                 LcdPrintNum(AlarmTL);
  382.                                 LcdGotoXY(0,7);                                // 重新定位閃爍的光標(biāo)位置
  383.                                 DelayMs(350);                                        // 延時(shí)
  384.                         }        
  385.                 }

  386.                 LcdGotoXY(0,10);
  387.                 DelayMs(10);                                                  // 去除按鍵按下的抖動(dòng)
  388.                 while(!KeySet_P);                                         // 等待按鍵釋放
  389.                 DelayMs(10);                                                  // 去除按鍵松開(kāi)的抖動(dòng)

  390.                 /*設(shè)置溫度的上限值****************************************************************/
  391.                                 
  392.                 while(KeySet_P)                                          // “設(shè)置鍵”沒(méi)有被按下,則一直處于溫度上限的設(shè)置
  393.                 {
  394.                         if(KeyDown_P==0)                                // 判斷 “減按鍵“ 是否被按下
  395.                         {
  396.                                 if(AlarmTH>0)                                  // 只有當(dāng)溫度上限值大于0時(shí),才能減1                        
  397.                                         AlarmTH--;
  398.                                 LcdGotoXY(0,9);                           // 重新刷新顯示更改后的溫度上限值
  399.                                 LcdPrintNum(AlarmTH);
  400.                                 LcdGotoXY(0,10);                        // 重新定位閃爍的光標(biāo)位置
  401.                                 DelayMs(350);                                        // 延時(shí)
  402.                         }
  403.                         if(KeyUp_P==0)                                   // 判斷 “加按鍵“ 是否被按下
  404.                         {
  405.                                 if(AlarmTH<99)                                 // 只有當(dāng)溫度上限值小于99時(shí),才能加1
  406.                                         AlarmTH++;
  407.                                 LcdGotoXY(0,9);                                // 重新刷新顯示更改后的溫度上限值         
  408.                                 LcdPrintNum(AlarmTH);
  409.                                 LcdGotoXY(0,10);                        // 重新定位閃爍的光標(biāo)位置
  410.                                 DelayMs(350);                                        // 延時(shí)
  411.                         }                                                                 
  412.                 }

  413.                 LcdGotoXY(1,7);
  414.                 DelayMs(10);                                                  // 去除按鍵按下的抖動(dòng)
  415.                 while(!KeySet_P);                                         // 等待按鍵釋放
  416.                 DelayMs(10);                                                  // 去除按鍵松開(kāi)的抖動(dòng)
  417.                
  418.                 /*設(shè)置濕度的下限值****************************************************************/

  419.                 while(KeySet_P)                                                 // “設(shè)置鍵”沒(méi)有被按下,則一直處于濕度下限的設(shè)置
  420.                 {
  421.                         if(KeyDown_P==0)                                // 判斷 “減按鍵“ 是否被按下
  422.                         {
  423.                                 if(AlarmHL>0)                                         // 只有當(dāng)濕度下限值大于0時(shí),才能減1
  424.                                         AlarmHL--;
  425.                                 LcdGotoXY(1,6);                                // 重新刷新顯示更改后的濕度下限值         
  426.                                 LcdPrintNum(AlarmHL);
  427.                                 LcdGotoXY(1,7);                                // 重新定位閃爍的光標(biāo)位置
  428.                                 DelayMs(350);
  429.                         }
  430.                         if(KeyUp_P==0)                                         // 判斷 “加按鍵“ 是否被按下
  431.                         {
  432.                                 if(AlarmHL<99)                          // 只有當(dāng)濕度下限值小于99時(shí),才能加1
  433.                                         AlarmHL++;
  434.                                 LcdGotoXY(1,6);                                  // 重新刷新顯示更改后的濕度下限值
  435.                                 LcdPrintNum(AlarmHL);
  436.                                 LcdGotoXY(1,7);                          // 重新定位閃爍的光標(biāo)位置
  437.                                 DelayMs(350);                                        // 延時(shí)
  438.                         }        
  439.                 }

  440.                 LcdGotoXY(1,10);
  441.                 DelayMs(10);                                                  // 去除按鍵按下的抖動(dòng)
  442.                 while(!KeySet_P);                                         // 等待按鍵釋放
  443.                 DelayMs(10);                                                  // 去除按鍵松開(kāi)的抖動(dòng)
  444.                
  445.                 /*設(shè)置濕度的上限值****************************************************************/

  446.                 while(KeySet_P)                                                 // “設(shè)置鍵”沒(méi)有被按下,則一直處于濕度上限的設(shè)置
  447.                 {
  448.                         if(KeyDown_P==0)                                 // 判斷 “減按鍵“ 是否被按下
  449.                         {
  450.                                 if(AlarmHH>0)                                  // 只有當(dāng)濕度上限值大于0時(shí),才能減1
  451.                                         AlarmHH--;
  452.                                 LcdGotoXY(1,9);                                  // 重新刷新顯示更改后的濕度上限值
  453.                                 LcdPrintNum(AlarmHH);
  454.                                 LcdGotoXY(1,10);                        // 重新定位閃爍的光標(biāo)位置
  455.                                 DelayMs(350);
  456.                         }
  457.                         if(KeyUp_P==0)                                         // 判斷 “加按鍵“ 是否被按下
  458.                         {
  459.                                 if(AlarmHH<99)                                // 只有當(dāng)濕度上限值小于99時(shí),才能加1
  460.                                         AlarmHH++;
  461.                                 LcdGotoXY(1,9);                                 // 重新刷新顯示更改后的濕度上限值        
  462.                                 LcdPrintNum(AlarmHH);
  463.                                 LcdGotoXY(1,10);                         // 重新定位閃爍的光標(biāo)位置
  464.                                 DelayMs(350);                                        // 延時(shí)
  465.                         }        
  466.                 }

  467.                 LcdWriteCmd(0x0C);                          // 取消光標(biāo)閃爍
  468.                 LcdShowInit();                                                // 液晶顯示為檢測(cè)界面的

  469.                 DelayMs(10);                                                  // 去除按鍵按下的抖動(dòng)
  470.                 while(!KeySet_P);                                         // 等待按鍵釋放
  471.                 DelayMs(10);                                                  // 去除按鍵松開(kāi)的抖動(dòng)

  472.                 Sector_Erase(0x2000);                                                 // 存儲(chǔ)之前必須先擦除
  473.                 EEPROM_Write(0x2000,AlarmTL);                // 把溫度下限存入到EEPROM的0x2000這個(gè)地址
  474.                 EEPROM_Write(0x2001,AlarmTH);                // 把溫度上限存入到EEPROM的0x2001這個(gè)地址
  475.                 EEPROM_Write(0x2002,AlarmHL);                // 把濕度下限存入到EEPROM的0x2002這個(gè)地址
  476.                 EEPROM_Write(0x2003,AlarmHH);                // 把濕度上限存入到EEPROM的0x2003這個(gè)地址
  477.         }        
  478. }



  479. // 主函數(shù)
  480. void main()
  481. {
  482.         uchar i;

  483.         LcdInit();                                                        // 液晶功能的初始化                        
  484.         LcdShowInit();                                         // 液晶顯示的初始化

  485.         AlarmTL=EEPROM_Read(0x2000);        // 從EEPROM的0x2000這個(gè)地址讀取溫度的報(bào)警下限
  486.         AlarmTH=EEPROM_Read(0x2001);        // 從EEPROM的0x2001這個(gè)地址讀取溫度的報(bào)警上限
  487.         AlarmHL=EEPROM_Read(0x2002);        // 從EEPROM的0x2002這個(gè)地址讀取濕度的報(bào)警下限        
  488.         AlarmHH=EEPROM_Read(0x2003);        // 從EEPROM的0x2003這個(gè)地址讀取濕度的報(bào)警上限

  489.         if((AlarmTL==0)||(AlarmTL>100))        // 如果溫度下限報(bào)警值讀出來(lái)異常(等于0或大于100),則重新賦值
  490.                 AlarmTL=20;
  491.         if((AlarmTH==0)||(AlarmTH>100))        // 如果溫度上限報(bào)警值讀出來(lái)異常(等于0或大于100),則重新賦值
  492.                 AlarmTH=35;
  493.         if((AlarmHL==0)||(AlarmHL>100))        // 如果溫度下限報(bào)警值讀出來(lái)異常(等于0或大于100),則重新賦值
  494.                 AlarmHL=40;
  495.         if((AlarmHH==0)||(AlarmHH>100))        // 如果溫度上限報(bào)警值讀出來(lái)異常(等于0或大于100),則重新賦值
  496.                 AlarmHH=85;
  497.                
  498.         
  499.         while(1)
  500.         {
  501.                 ReadDhtData();                                 // 檢測(cè)溫濕度數(shù)據(jù)

  502.                 LcdGotoXY(1,2);                                 // 定位到要顯示溫度的地方
  503.                 LcdPrintNum(temp);                // 顯示溫度值
  504.                 LcdGotoXY(1,11);                        // 定位到要顯示濕度的地方
  505.                 LcdPrintNum(humi);                // 顯示濕度值
  506.                
  507.                 AlarmJudge();                                        // 判斷并根據(jù)需要報(bào)警

  508.                 for(i=0;i<25;i++)
  509.                 {
  510.                         KeyScanf();                                        // 按鍵掃描
  511.                         DelayMs(20);                                // 延時(shí)        
  512.                 }
  513.         }
  514. }
復(fù)制代碼



回復(fù)

使用道具 舉報(bào)

ID:894722 發(fā)表于 2021-5-17 21:21 | 顯示全部樓層
當(dāng)我把主函數(shù)的    ReadDhtData();           注釋掉時(shí),能夠完成按鍵等操作。
一旦把它放在主函數(shù)里,仿佛卡在這個(gè)readdhtdate()函數(shù)中了。
回復(fù)

使用道具 舉報(bào)

ID:894722 發(fā)表于 2021-5-17 22:40 | 顯示全部樓層
問(wèn)題很簡(jiǎn)單 就是想把ReadDhtDate()函數(shù)中的錯(cuò)誤找出來(lái)并且嘗試改正它 ,其它部分都沒(méi)有問(wèn)題 。希望大佬指點(diǎn)   頂一下   
回復(fù)

使用道具 舉報(bào)

ID:748788 發(fā)表于 2021-6-6 16:10 | 顯示全部樓層
dht11對(duì)時(shí)序要求比較嚴(yán)格,也就是各種延時(shí)要盡量準(zhǔn)確,而網(wǎng)上常見(jiàn)的延時(shí)函數(shù)在不同單片機(jī)下的延時(shí)時(shí)間并不一致。我曾經(jīng)測(cè)試過(guò)10個(gè)nop組成的delay10us函數(shù),結(jié)果延遲時(shí)間只有4us。你最好測(cè)試一下用到的延時(shí)函數(shù)的真實(shí)數(shù)值。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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