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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

溫濕度采集和測量系統的Proteus仿真(基于STC89C51+STH11+LCD1602)

  [復制鏈接]
跳轉到指定樓層
樓主
ID:1002955 發表于 2022-3-15 11:09 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
一、設計的技術要求:



    溫濕度測量系統的軟件部分是以Keil為開發平臺,C語言為軟件系統的開發語言,同時采用模塊化編程。具體分為以下幾個部分:主控制、溫濕度采集程序、溫濕度數據處理程序、LCD顯示程序、按鍵設置程序和LED,蜂鳴器報警程序。系統通過SHT11溫濕度傳感器感應周圍的環境的溫度和濕度,通過單片機對采集到的數據進行讀取處理,經過LCD1602顯示模塊實時顯示溫濕度數據,同時可以通過按鍵模塊對溫濕度報警上、下限值進行設定。當SHT11讀取的溫濕度值不在設定范圍內時,報警模塊LED燈指示故障信息,同時蜂鳴器報警;當溫濕度讀取數據正常后,LED燈熄滅,蜂鳴器關閉。

實現功能1:(SHT11讀取處理+LCD1602顯示模塊
實現功能2按鍵模塊對溫濕度報警上、下限值進行設定。
實現功能3SHT11讀取的溫濕度值不在設定范圍內時,報警模塊LED燈指示故障信息,同時蜂鳴器報警;當溫濕度讀取數據正常后,LED燈熄滅,蜂鳴器關閉。



四、代碼

  1. /***********************************************************************************
  2. ;功能說明:SHT11和STC89C51溫濕度采集和測量系統的Proteus仿真
  3. ;文件名稱:DU.c   
  4. ;版本號:v1.0.0  
  5. ;微處理器:STC89C51
  6. ;編譯環境:Keil uVision V4.10
  7. ;作    者:Cui Xinghai
  8. ;創建日期:2022.2.24   
  9. ;***********************************************************************************/

  10. /*************定義接口********************
  11.          P0------DB0~DB7  (LCD1602)     
  12.          P2.0------RS      (LCD1602)
  13.          P2.1------RW      (LCD1602)
  14.          P2.2------E       (LCD1602)

  15.                  P2.6------SCK     (STH11)
  16.                  P2.7------DATA    (STH11)

  17.                  P1.5------SET     //定義調整鍵
  18.                  P1.6------ADD           //定義增加鍵
  19.                  P1.7------DEC     //定義減少鍵
  20.          P3.7------ESC     //定義退出鍵
  21.                  P1.4------BEEP    //定義蜂鳴器

  22.                  P1.0------t_green                     //溫度過低燈
  23.                  P1.1------t_red                     //溫度過高燈
  24.                  P1.2------rh_green                     //濕度過低燈
  25.                  P1.3------rh_red                     //濕度過高燈
  26. *****************************************/

  27. #include <reg52.h>         
  28. #include <intrins.h> //應用于程序設計,一般出C51單片機編程中,一般程序中需要使用到空指令_nop_();字符循環移位指令_crol_等時使用。
  29. #include <math.h>    //Keil library   
  30. #include <stdio.h>   //Keil library


  31. //*********************第一部分LCD1602設置 START****************************************
  32. #define      LCD_DB P0             //Data Bus數據總線,我們這里要做 1602 液晶的程序,因此先把用到的總線接口做一個統一聲明
  33. sbit         LCD_RS=P2^0;   
  34. sbit         LCD_RW=P2^1;   
  35. sbit         LCD_E =P2^2;  
  36.                   
  37. /******定義函數****************/
  38. #define uchar unsigned char
  39. #define uint unsigned int

  40. void LCD_init(void);                           //初始化函數
  41. void LCD_write_command(uchar command);         //寫指令函數
  42. void LCD_write_data(uchar dat);                //寫數據函數
  43. void LCD_disp_char(uchar x,uchar y,uchar dat); //在某個屏幕位置上顯示一個字符,X(0-15),y(1-2)
  44. void LCD_disp_str(uchar x,uchar y,uchar *str); //LCD1602顯示字符串函數
  45. void delay_n10us(uint n);                      //延時函數

  46. /*--------------------------------------
  47. ;模塊名稱:LCD_init();
  48. ;功    能:初始化LCD1602
  49. ;-------------------------------------*/
  50. void LCD_init(void)                //括號中的void意思該函數的參數為空
  51. {
  52. delay_n10us(10);
  53. LCD_write_command(0x38);//指令6:工作方式設置指令,0x0011 1000設置8位格式數據接口,16*2行顯示,5x7點陣
  54. delay_n10us(10);
  55. LCD_write_command(0x0c);//指令4:
  56.                                                 //整體顯示,關光標,不閃爍,BCD0x00001 100
  57.                                                 //整體顯示,開光標,  閃爍,BCD0x00001 111
  58. delay_n10us(10);
  59. LCD_write_command(0x06);//指令3:設定輸入方式增量不移位,    0x00000110
  60. delay_n10us(10);
  61. LCD_write_command(0x01);//指令1:清除屏幕顯示,光標復位到地址00H位置
  62. delay_n10us(100);       //延時清屏,延時函數,延時約n個10us
  63. }


  64. /*--------------------------------------
  65. ;模塊名稱:LCD_write_command();
  66. ;功    能:LCD1602寫指令函數
  67. ;占用資源: P2.0--RS(LCD_RS),P2.1--RW(LCD_RW),P2.2--E(LCD_E).
  68. ;參數說明:dat為寫命令參數
  69. ;-------------------------------------*/
  70. void LCD_write_command(uchar dat)
  71. {
  72. delay_n10us(10);
  73. LCD_RS=0;         //指令
  74. LCD_RW=0;         //寫入
  75. LCD_E=1;          //允許
  76. LCD_DB=dat;
  77. delay_n10us(10);  //實踐證明,我的LCD1602上,用for循環1次就能完成普通寫指令。
  78. LCD_E=0;                  //讀完撤銷使能,防止液晶輸出數據干擾 P0 總線
  79. delay_n10us(10);  //實踐證明,LCD1602上,用for循環1次就能完成普通寫指令。
  80. }


  81. /*--------------------------------------
  82. ;模塊名稱:LCD_write_data();
  83. ;功    能:LCD1602寫數據函數
  84. ;占用資源: P2.0--RS(LCD_RS),P2.1--RW(LCD_RW),P2.2--E(LCD_E).
  85. ;參數說明:dat為寫數據參數
  86. ;-------------------------------------*/
  87. void LCD_write_data(uchar dat)
  88. {
  89. delay_n10us(10);
  90. LCD_RS=1;          //數據
  91. LCD_RW=0;          //寫入
  92. LCD_E=1;           //允許
  93. LCD_DB=dat;
  94. delay_n10us(10);
  95. LCD_E=0;
  96. delay_n10us(10);
  97. }


  98. /*--------------------------------------
  99. ;模塊名稱:LCD_disp_char();
  100. ;功    能:光標位置,LCD1602顯示一個字符函數,在某個屏幕位置上顯示一個字符,X(0-15),y(1-2)。
  101. ;參數說明:X為1602的列值(取值范圍是0-15),y為1602的行值(取值范圍是1-2),dat為所要顯示字符對應的地址參數。
  102. ;-------------------------------------*/
  103. void LCD_disp_char(uchar x,uchar y,uchar dat)
  104. {
  105.   uchar address;
  106.   if(y==1)                                 //0x80和00H的區別:指令7
  107.          address=0x80+x; //二進制碼中第一行首地址為10000000轉換16進制為0x80,第二行首地址為11000000轉換16進制為0xC0 加首地址是為了讓LCD顯示從第一位開始顯示。
  108.   else
  109.          address=0xc0+x;
  110.   LCD_write_command(address);
  111.   LCD_write_data(dat);
  112. }



  113. /*--------------------------------------
  114. ;模塊名稱:LCD_disp_str();
  115. ;功    能:LCD1602顯示字符串函數,在某個屏幕起始位置{X(0-15),y(1-2)}上顯示一個字符串。
  116. ;參數說明:X為1602的列值(取值范圍是0-15),y為1602的行值(取值范圍是1-2),str為所要顯示字符串對應的指針參數。
  117. ;-------------------------------------*/
  118. void LCD_disp_str(uchar x,uchar y,uchar *str)
  119. {
  120.   uchar address;
  121.   if(y==1)
  122.          address=0x80+x;
  123.   else
  124.          address=0xc0+x;
  125.   LCD_write_command(address);  //連續寫入字符串數據,直到檢測到結束符
  126.   while(*str!='\0')
  127.   {
  128.     LCD_write_data(*str);      //另外一種寫法LCD_write_data(*str++)這行語句中對指針 str 的操作大家一定要理解透徹,先把 str指向的數據取出來用,然后 str 再加 1 以指向下一個數據,這是非常常用的一種簡寫方式
  129.     str++;
  130.   }
  131. }


  132. /*--------------------------------------
  133. ;模塊名稱:delay_n10us();
  134. ;功    能:延時函數,延時約n個10us
  135. ;修改日期:2022.02.26
  136. ;修改說明:修改為較精確的延時函數,"_nop_()"延時1us@12M晶振,代表運行一個機器周期。如果這個單片機的晶振是12M的,那么這調代碼會運行1US;
  137. ;-------------------------------------*/
  138. void delay_n10us(uint n)  //延時n個10us@12M晶振
  139. {      
  140.         uint i;           
  141.         for(i=n;i>0;i--)   
  142.         {
  143.         _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  144.                 }
  145. }                                    
  146. //*********************第一部分LCD1602設置 END****************************************



  147. //*********************第二部分SHT11設置   START****************************************
  148. sbit SCK  = P2^6;      //定義通訊時鐘端口
  149. sbit DATA = P2^7;      //定義通訊數據端口

  150. typedef union                     //定義了兩個共用體:如果沒有typedef那么就是普通的定義了匿名聯合的一個變量value.加了typedef后, 定義的就是類型別名, 當類型一樣用
  151. {
  152. unsigned int i;        //i表示測量得到的溫濕度數據(int 形式保存的數據)
  153.   float f;                            //f表示測量得到的溫濕度數據(float 形式保存的數據)
  154. } value;

  155. enum {TEMP,HUMI};      //enum 枚舉名 {枚舉元素1,枚舉元素2,……};TEMP=0,HUMI=1        枚舉


  156. #define noACK        0      //用于判斷是否結束通訊
  157. #define ACK          1      //結束數據傳輸
  158.                             //adr  command  r/w
  159. #define STATUS_REG_W 0x06   //000   0011    0
  160. #define STATUS_REG_R 0x07   //000   0011    1
  161. #define MEASURE_TEMP 0x03   //000   0001    1
  162. #define MEASURE_HUMI 0x05   //000   0010    1
  163. #define RESET        0x1e   //000   1111    0

  164. /****************定義函數****************/
  165. void s_transstart(void);               //啟動傳輸函數
  166. void s_connectionreset(void);          //連接復位函數
  167. char s_write_byte(unsigned char value);//寫函數
  168. char s_read_byte(unsigned char ack);   //讀函數
  169. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);//測量溫濕度函數
  170. void calc_SHT11(float *p_humidity ,float *p_temperature);//溫濕度補償



  171. /*--------------------------------------
  172. ;模塊名稱:s_transstart();
  173. ;功    能:啟動傳輸函數
  174. ;-------------------------------------*/  
  175. void s_transstart(void)
  176. // generates a transmission start (SHT11發送命令,啟動傳輸時序)  
  177. //       _____         ________
  178. // DATA:      |_______|
  179. //           ___     ___
  180. // SCK : ___|   |___|   |______
  181. {   
  182.    DATA=1; SCK=0;                   //Initial state
  183.    _nop_();
  184.    SCK=1;
  185.    _nop_();
  186.    DATA=0;
  187.    _nop_();
  188.    SCK=0;   
  189.    _nop_();_nop_();_nop_();
  190.    SCK=1;
  191.    _nop_();
  192.    DATA=1;        
  193.    _nop_();
  194.    SCK=0;        
  195. }

  196. /*--------------------------------------
  197. ;模塊名稱:s_connectionreset();
  198. ;功    能:連接復位函數
  199. ;-------------------------------------*/
  200. void s_connectionreset(void)
  201. // 通訊復位時序:如果與 SHT11 通訊中斷,下列信號時序可以復位串口:DATA 保持高電平時,觸發 SCK 時鐘 9 次或更多。
  202. //       _____________________________________________________         ________
  203. // DATA:                                                      |_______|
  204. //          _    _    _    _    _    _    _    _    _        ___     ___
  205. // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
  206. {   
  207.   unsigned char i;  
  208.   DATA=1; SCK=0;                    //Initial state
  209.   for(i=0;i<9;i++)                  //9 SCK cycles,DATA保持高,SCK時鐘觸發9次,發送啟動傳輸,通迅即復位
  210.   {
  211.     SCK=1;
  212.     SCK=0;
  213.   }
  214.   s_transstart();                   //transmission start
  215. }


  216. /*--------------------------------------
  217. ;模塊名稱:s_write_byte();
  218. ;功    能:SHT11寫函數                                                
  219. ;-------------------------------------*/
  220. char s_write_byte(unsigned char value)
  221. //----------------------------------------------------------------------------------
  222. // 寫入一個字節,并檢查確認
  223. {  
  224.   unsigned char i,error=0;
  225.      
  226.   for (i=0x80;i>0;i/=2)             //0x1000 0000用于掩碼的移位,高位為1,循環右移 https://zhidao.baidu.com/question/2144112204880805988.html
  227.   {  
  228.     if (i & value) DATA=1;          //和要發送的數相與,結果為發送的位
  229.               else DATA=0;                        
  230.     SCK=1;                           
  231.     _nop_();_nop_();_nop_();            
  232.     SCK=0;
  233.   }

  234.   DATA=1;                           //釋放數據線
  235.   SCK=1;                            //clk #9 for ack  
  236.   error=DATA;                       //檢查應答信號,確認通訊正常  
  237.   _nop_();_nop_();_nop_();
  238.   SCK=0;
  239.   DATA=1;                           //
  240.   return error;                     //error=1 in case of no acknowledge //返回:0成功,1失敗
  241. }                        


  242. /*--------------------------------------
  243. ;模塊名稱:s_read_byte();
  244. ;功    能:SHT11讀函數
  245. ;-------------------------------------*/
  246. char s_read_byte(unsigned char ack)   
  247. {  
  248.   unsigned char i,val=0;
  249.   DATA=1;                           //釋放數據線
  250.   for (i=0x80;i>0;i/=2)              
  251.   {
  252.     SCK=1;                          //clk for SENSI-BUS
  253.     if (DATA) val=(val | i);        //讀一位數據線的值   
  254.         _nop_();_nop_();_nop_();        //pulswith approx. 3 us
  255.     SCK=0;              
  256.   }
  257.   if(ack==1)DATA=0;                 //in case of "ack==1" pull down DATA-Line
  258.   else DATA=1;                      //如果是校驗(ack==0),讀取完后結束通訊
  259.   _nop_();_nop_();_nop_();          //pulswith approx. 3 us
  260.   SCK=1;                            //clk #9 for ack
  261.   _nop_();_nop_();_nop_();          //pulswith approx. 3 us  
  262.   SCK=0;                 
  263.   _nop_();_nop_();_nop_();          //pulswith approx. 3 us
  264.   DATA=1;                           //release DATA-line
  265.   return val;
  266. }




  267. /*--------------------------------------
  268. ;模塊名稱:s_measure();
  269. ;功    能:測量溫濕度函數
  270. ;-------------------------------------*/
  271. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
  272. // 進行溫度或者濕度轉換,由參數mode決定轉換內容
  273. {  
  274.   unsigned error=0;
  275.   unsigned int i;

  276.   s_transstart();                   //transmission start

  277.   switch(mode){                     //選擇發送命令
  278.     case TEMP  : error+=s_write_byte(MEASURE_TEMP); break;
  279.     case HUMI  : error+=s_write_byte(MEASURE_HUMI); break;
  280.     default     : break;   
  281.   }
  282.   for (i=0;i<65535;i++) if(DATA==0) break; //等待測量結束
  283.   if(DATA) error+=1;                // 如果長時間數據線沒有拉低,說明測量錯誤
  284.   *(p_value)  =s_read_byte(ACK);    //讀第一個字節,高字節 (MSB)
  285.   *(p_value+1)=s_read_byte(ACK);    //讀第二個字節,低字節 (LSB)
  286.   *p_checksum =s_read_byte(noACK);  //read checksum
  287.    return error;
  288. }


  289. /*--------------------------------------
  290. ;模塊名稱:calc_SHT11();
  291. ;功    能:溫濕度補償函數
  292. ;備    注:SHT11濕度測量范圍:0~100%RH;溫度測量范圍:-40~+123.8℃
  293. ;-------------------------------------*/
  294. void calc_SHT11(float *p_humidity ,float *p_temperature)
  295. // calculates temperature [C] and humidity [%RH]
  296. // input :  humi [Ticks] (12 bit)
  297. //          temp [Ticks] (14 bit)
  298. // output:  humi [%RH]
  299. //          temp [C]
  300.                                     //const表示常量,不允許修改里面的內容
  301. { const float C1=-4.0;              // 12位濕度精度 修正公式
  302.   const float C2=+0.0405;           // 12位濕度精度 修正公式
  303.   const float C3=-0.0000028;        // 12位濕度精度 修正公式
  304.   const float T1=+0.01;             // 14位溫度精度 5V條件  修正公式
  305.   const float T2=+0.00008;          // 14位溫度精度 5V條件  修正公式

  306.   float rh=*p_humidity;             // rh:      Humidity [Ticks] 12 Bit
  307.   float t=*p_temperature;           // t:       Temperature [Ticks] 14 Bit
  308.   float rh_lin;                     // rh_lin:  Humidity linear
  309.   float rh_true;                    // rh_true: Temperature compensated humidity
  310.   float t_C;                        // t_C   :  Temperature [C]

  311.   t_C=t*0.01 - 40;                  //補償溫度,14位溫度精度 5V條件  修正公式
  312.   
  313.   rh_lin=C3*rh*rh + C2*rh + C1;     //相對濕度非線性補償
  314.   rh_true=(t_C-25)*(T1+T2*rh)+rh_lin-3;   //相對濕度對于溫度依賴性補償

  315.   if(rh_true>100)rh_true=100;       //濕度最大修正
  316.   if(rh_true<0.1)rh_true=0.1;       //濕度最小修正

  317.   *p_temperature=t_C;               //返回溫度結果
  318.   *p_humidity=rh_true;              //返回濕度結果
  319. }
  320. //*********************第二部分STH11設置   END****************************************


  321. //*********************第三部分報警設置   START****************************************
  322. #define N   0x00
  323. sbit SET =         P1^5;                   //定義調整鍵
  324. sbit ADD =        P1^6;                   //定義增加鍵
  325. sbit DEC =         P1^7;                   //定義減少鍵
  326. sbit ESC =  P3^7;                   //定義調整鍵
  327. sbit BEEP=  P1^4;                   //定義蜂鳴器

  328. sbit  t_green   =  P1^0;
  329. sbit  t_red     =  P1^1;
  330. sbit  rh_green  =  P1^2;
  331. sbit  rh_red    =  P1^3;

  332. int t_shangxian = 20;            //上限報警溫度,默認值為 20C
  333. int t_xiaxian   = 10;            //下限報警溫度,默認值為 10C
  334. int rh_shangxian= 50;            //上限報警濕度,默認值為50%
  335. int rh_xiaxian  = 40;            //下限報警濕度,默認值為40%

  336. uchar flag=0;


  337. /****************定義函數****************/
  338. void led_control( float *WENDU,  float *SHIDU);
  339. void key();
  340. void delay(uint j);
  341. /*--------------------------------------
  342. ;模塊名稱:led_control();
  343. ;功    能:LED狀態控制
  344. ;-------------------------------------*/
  345. void led_control( float *WENDU,  float *SHIDU)                  
  346. {
  347. //溫度過低報警指示
  348.   if(*WENDU <= t_xiaxian)    {t_green = 0;}
  349.   else {t_green=1;}
  350. //溫度過高報警指示
  351.   if(*WENDU >= t_shangxian)  {t_red   = 0;}
  352.   else {t_red=1;}
  353. //濕度過低報警指示
  354.   if(*SHIDU <= rh_xiaxian)   {rh_green= 0;}
  355.   else {rh_green=1;}
  356. //濕度過高報警指示
  357.   if(*SHIDU >= rh_shangxian) {rh_red  = 0;}
  358.   else {rh_red=1;}
  359. //蜂鳴器警示
  360.   if(*WENDU <= t_xiaxian||*WENDU >= t_shangxian||*SHIDU <= rh_xiaxian||*SHIDU >= rh_shangxian)
  361.   {
  362.     BEEP = 0;
  363.   }
  364.   else
  365.   {
  366.     BEEP = 1;
  367.   }
  368. }

  369.            
  370. /*--------------------------------------
  371. ;模塊名稱:key();
  372. ;功    能:按鍵控制
  373. ;-------------------------------------*/
  374. void key()   
  375. {
  376. /****************設置鍵設置****************/
  377. if(SET == 0)
  378.   {
  379.     delay(50);               //按鍵消抖
  380.     if(SET == 0)
  381.      {
  382.       flag++;
  383.       if (flag==5)flag = 0;  //沒有發生抖動
  384.           while(SET==0);         //若一直按下,循環

  385.     LCD_init();
  386.     s_connectionreset();     
  387.     LCD_disp_str(0,1,"TE:");
  388.     LCD_disp_str(0,2,"RH:");
  389.         LCD_disp_str(6,1,"-");
  390.         LCD_disp_str(6,2,"-");
  391.         LCD_disp_str(10,1,"C");
  392.         LCD_disp_str(10,2,"%");
  393.     delay_n10us(20);      
  394.     }

  395.   }
  396. //SHT11濕度測量范圍:0~100%RH;溫度測量范圍:-40~+123.8℃;
  397. /****************溫度下限設置****************/
  398.         if (flag==1)                                 
  399.      {
  400.       if(ADD==0)
  401.            {
  402.             delay(50);
  403.             t_xiaxian++;
  404.             if (t_xiaxian>(t_shangxian-1)) {t_xiaxian=(t_shangxian-1);}
  405.                 while(ADD==0);                                        //加上此句必須松按鍵才處理
  406.            }
  407.            if (DEC==0)
  408.            {
  409.             delay(50);                    
  410.             if(t_xiaxian<=-40)    {t_xiaxian=t_shangxian;}              //超過實際范圍,重新賦值溫度下限
  411.             else                                    t_xiaxian--;
  412.             while(DEC==0);                                        //加上此句必須松按鍵才處理
  413.            }
  414.        //溫度下限顯示
  415.                 LCD_disp_char(3,1,t_xiaxian/100+'0');                 //例如123/100=1
  416.                 LCD_disp_char(4,1,abs(t_xiaxian%100/10)+'0');         //例如123%100=23,23/10 =2 ,-12取絕對值12           
  417.         LCD_disp_char(5,1,abs(t_xiaxian%10)+'0');                           //例如123%10 =3
  418.         if(t_xiaxian<0)    {LCD_disp_str(12,2,"nega");}              //溫度下限為負數,顯示nega
  419.                  else                            {LCD_disp_str(12,2,"    ");}                  //去除負數提醒nega
  420.          }

  421. /****************溫度上限設置****************/
  422.         if (flag==2)              
  423.           {
  424.            if(ADD==0)
  425.            {
  426.             delay(150);
  427.             t_shangxian++;
  428.             if (t_shangxian>123) {t_shangxian=123;}              //上限值達到最大值 123時,上限值保持為123
  429.             while(ADD==0);                                       //加上此句必須松按鍵才處理
  430.            }
  431.            if (DEC==0)
  432.            {
  433.             delay(150);
  434.             t_shangxian--;
  435.             if (t_shangxian<(t_xiaxian+1)) {t_shangxian=(t_xiaxian+1);}//確保設定的上限值不比下限低
  436.             while(DEC==0);                                       //加上此句必須松按鍵才處理
  437.            }
  438.        //溫度上限顯示
  439.                 LCD_disp_char(7,1,t_shangxian/100+'0');
  440.             LCD_disp_char(8,1,(t_shangxian%100)/10+'0');         
  441.             LCD_disp_char(9,1,(t_shangxian%10)+'0');      
  442.           }

  443. /****************濕度下限設置****************/
  444.         if (flag==3)            
  445.           {
  446.            if(ADD==0)
  447.            {
  448.             delay(150);
  449.             rh_xiaxian++;
  450.             if (rh_xiaxian>(rh_shangxian-1)) {rh_xiaxian=(rh_shangxian-1);}
  451.             while(ADD==0);                                      //加上此句必須松按鍵才處理
  452.            }
  453.            if (DEC==0)
  454.            {
  455.             delay(150);   
  456.             if (rh_xiaxian<=0) {rh_xiaxian=0;}                                        //下限值達到最小值0時,下限值保持為0
  457.             else rh_xiaxian--;
  458.             while(DEC==0);                                      //加上此句必須松按鍵才處理
  459.            }
  460.        //濕度下限顯示
  461.                 LCD_disp_char(3,2,rh_xiaxian/100+'0');
  462.             LCD_disp_char(4,2,(rh_xiaxian%100)/10+'0');               
  463.             LCD_disp_char(5,2,(rh_xiaxian%10)+'0');
  464.           }


  465. /****************濕度上限設置****************/
  466.     if (flag==4)              
  467.           {
  468.            if(ADD==0)
  469.            {
  470.             delay(150);
  471.             rh_shangxian++;
  472.             if (rh_shangxian>99) {rh_shangxian=99;}            //上限值達到最大值 99時,上限值保持為 99
  473.             while(ADD==0);                                     //加上此句必須松按鍵才處理
  474.            }
  475.            if (DEC==0)
  476.            {
  477.             delay(150);
  478.             rh_shangxian--;
  479.             if (rh_shangxian<(rh_xiaxian+1)) {rh_shangxian=(rh_xiaxian+1);}//確保設定的上限值不比下限低
  480.             while(DEC==0);                                     //加上此句必須松按鍵才處理
  481.            }
  482.        //濕度上限顯示
  483.                 LCD_disp_char(7,2,rh_shangxian/100+'0');         
  484.             LCD_disp_char(8,2,(rh_shangxian%100)/10+'0');         
  485.             LCD_disp_char(9,2,(rh_shangxian%10)+'0');     
  486.           }

  487. /****************退出鍵設置****************/                                             
  488. if(ESC==0)                     
  489. {                                          
  490.   delay(10);
  491.   if(ESC==0)
  492.     {           
  493.          while(ESC==0);
  494.          flag=0;
  495.      LCD_init();
  496.      s_connectionreset();     
  497.      }

  498.   }
  499. }  


  500. /*--------------------------------------
  501. ;模塊名稱:delay();
  502. ;功    能:延遲函數
  503. ;-------------------------------------*/
  504. void delay(uint j)                        //1ms,j取20
  505. {
  506.         uchar i=250;
  507.         for(;j>0;j--)
  508.         {
  509.                 while(--i);
  510.                 i=249;
  511.                 while(--i);
  512.                 i=250;
  513.         }
  514. }

  515. //*********************第三部分報警設置   END****************************************


  516. //*********主函數*****************
  517. void main(void)
  518. {
  519.                value humi_val,temp_val;                                     //185行,定義兩個共同體,一個用于濕度,一個用于溫度
  520.                unsigned char error,checksum;                          //用于檢驗是否出現錯誤
  521.                unsigned int wendu,shidu;                                 //最終,一位小數溫濕度的值
  522.                    LCD_init();  
  523.            s_connectionreset();
  524.      
  525. //*********初始化溫度顯示區*********
  526.            LCD_disp_str(0,1,"TE:");
  527.            LCD_disp_str(3,1,"TTT.TC");

  528. //*********初始化濕度顯示區*********
  529.            LCD_disp_str(0,2,"RH:");
  530.                    LCD_disp_str(3,2,"RRR.R%");
  531.            delay_n10us(2000);     //延時0.2s

  532.   while(1)
  533.         {
  534.                   LCD_disp_char(13,1,flag+'0');

  535.           key();
  536.      
  537.          if(flag==0)
  538.           {
  539.            error=0;                                                                                  //初始化error=0,即沒有錯誤
  540.            error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);  //measure humidity
  541.            error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);  //measure temperature
  542.            if(error!=0) s_connectionreset();                 //in case of an error: connection reset
  543.            else
  544.             {
  545.              humi_val.f=(float)humi_val.i;                   //converts integer to float
  546.              temp_val.f=(float)temp_val.i;                   //converts integer to float
  547.              calc_SHT11(&humi_val.f,&temp_val.f);            //calculate humidity, temperature
  548.                               
  549.              LCD_disp_str(0,1,"TE:");
  550.              LCD_disp_str(0,2,"RH:");
  551.              LCD_disp_str(6,1,".");
  552.              LCD_disp_str(6,2,".");
  553.              LCD_disp_str(8,1,"C   ");
  554.              LCD_disp_str(8,2,"%   ");

  555.                      wendu=10*temp_val.f;                            //例如溫度109.1→1091
  556.                         
  557.                          if(10*temp_val.f<0) {LCD_disp_str(12,2,"nega");}//實時溫度為負數時,顯示提示符nega        
  558.                      else {LCD_disp_str(12,2,"    ");}                         //實時溫度為正數時,去除負數提醒nega
  559.                         
  560.                          LCD_disp_char(3,1,abs(wendu)/1000+'0');         //顯示溫度百位,加“0”是為了將字符的ASCII碼大于48(即字符0的ASCII值),一般是將數字0,1,2……,9轉換為字符“0”,“1”……,“9”;                        
  561.                          LCD_disp_char(4,1,abs(wendu)%1000/100+'0');     //顯示溫度十位
  562.              LCD_disp_char(5,1,abs(wendu)%100/10+'0');       //顯示溫度個位
  563.                      LCD_disp_char(7,1,abs(wendu)%10+'0');           //顯示溫度小數點后第一位

  564.                          shidu=10*humi_val.f;
  565.                          LCD_disp_char(3,2,shidu/1000+'0');               //顯示濕度百位
  566.              LCD_disp_char(4,2,(shidu%1000)/100+'0');         //顯示濕度十位
  567.              LCD_disp_char(5,2,(shidu%100)/10+'0');           //顯示濕度個位
  568.                          LCD_disp_char(7,2,(shidu%10)+'0');               //顯示濕度小數點后第一位
  569.          
  570.              led_control(&temp_val.f,&humi_val.f);

  571.            }
  572.           //----------wait approx. 0.8s to avoid heating up SHT11------------------------------      
  573.                   delay_n10us(800);                                //延時約0.8s      
  574.                   }

  575.       

  576.       }
  577. }
復制代碼

Keil代碼與Proteus仿真下載: STC89C51+STH11.7z (4.26 MB, 下載次數: 161)

評分

參與人數 1黑幣 +30 收起 理由
admin + 30 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:1002955 發表于 2022-3-15 11:19 | 只看該作者
新人,有什么不足的希望大佬指點
回復

使用道具 舉報

板凳
ID:1002955 發表于 2022-3-18 20:53 | 只看該作者
文檔部分改了一些,有什么不足之處 請指正 STC89C51+STH11.7z (3.81 MB, 下載次數: 74)
回復

使用道具 舉報

地板
ID:64253 發表于 2022-4-5 15:25 | 只看該作者
看上去很不錯的樣子,研究下思路
回復

使用道具 舉報

5#
ID:1012191 發表于 2022-4-7 19:41 | 只看該作者
Proteus8.12以上才能打開
回復

使用道具 舉報

6#
ID:297903 發表于 2022-4-8 10:16 | 只看該作者
這格式看上去老用心了!!
回復

使用道具 舉報

7#
ID:1017131 發表于 2022-4-13 16:50 | 只看該作者
為什么我運行不了,仿真都沒現象
回復

使用道具 舉報

8#
ID:982617 發表于 2022-4-13 17:15 | 只看該作者
很棒啊,急需就用到了。學習到了,感謝。!
回復

使用道具 舉報

9#
ID:1017646 發表于 2022-4-18 21:55 | 只看該作者
仿真圖為什么我打不開呢 一打開就回到原界面,我的是8.12版本
回復

使用道具 舉報

10#
ID:1002955 發表于 2022-4-22 08:45 | 只看該作者
candy0122 發表于 2022-4-13 16:50
為什么我運行不了,仿真都沒現象

發個圖我看看
回復

使用道具 舉報

11#
ID:1002955 發表于 2022-4-22 08:49 | 只看該作者
polar0806 發表于 2022-4-18 21:55
仿真圖為什么我打不開呢 一打開就回到原界面,我的是8.12版本

同版本應該沒問題
回復

使用道具 舉報

12#
ID:1002955 發表于 2022-4-22 08:50 | 只看該作者
candy0122 發表于 2022-4-13 16:50
為什么我運行不了,仿真都沒現象

這個與單片機仿真軟件版本有關,在高版本中制作的仿真文件在低版本軟件中運行可能會出現這種情況。
還有一個就是配置hex文件路徑
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩中文电影 | 久久不卡日韩美女 | 久久国产精品视频观看 | 成人精品在线观看 | 黄瓜av | 成人无遮挡毛片免费看 | 欧美天堂 | 国产不卡在线播放 | 特级毛片爽www免费版 | 又爽又黄axxx片免费观看 | 久久久成人免费一区二区 | 在线欧美小视频 | 精品国产一二三区 | 国产成人叼嘿视频在线观看 | 999热精品| 日韩国产免费观看 | 国产色网站 | 亚洲高清在线 | 99精品网| 国产精品久久久久久久久久久久久久 | 国产农村妇女毛片精品久久麻豆 | 一级黄色毛片免费 | 国产乱码高清区二区三区在线 | 在线免费国产 | 久久久久久久国产 | 日韩波多野结衣 | 成人午夜高清 | 国产成人99久久亚洲综合精品 | 亚洲精品九九 | 亚洲国产精品久久久 | 免费观看日韩av | 97久久精品 | 国产在线网站 | 精品国产乱码久久久久久影片 | 五月婷六月丁香 | 日日射夜夜骑 | 亚州精品天堂中文字幕 | 亚洲成人毛片 | 国产精品久久 | 国产一区二区免费 | 国产一级淫片免费视频 |