找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2983|回复: 6
打印 上一主题 下一主题
收起左侧

如何将单点SHT11温湿度传感器测量系统改为多点的?

[复制链接]
跳转到指定楼层
楼主
如何将单点SHT11温湿度传感器测量系统改为多点的?





  1. /*************端口定义********************
  2.          P1.0------SCK     (SHT11)
  3.          P1.1------DATA    (SHT11)
  4.          P0------DB0~DB7  (LCD1602)     
  5.          P2.0------RS      (LCD1602)
  6.          P2.1------RW      (LCD1602)
  7.          P2.2------E       (LCD1602)
  8. *****************************************/
  9. #include <reg52.h>
  10. #include <intrins.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <absacc.h>
  14. #include <math.h>

  15. #define uchar unsigned char
  16. #define uint unsigned int

  17. #define TEMPUP 25       //温度上限
  18. #define TEMPDOWN 18           //温度下限
  19. #define HUMDOWN 45           //湿度上限
  20. #define HUMUP  75              //湿度下限

  21. sbit LcdRs= P2^0;   //1602液晶端口定义
  22. sbit LcdRw= P2^1;
  23. sbit LcdEn= P2^2;
  24. sbit led1 =P3^0;    //报警灯端口定义
  25. sbit led2 =P3^4;
  26. sbit beep =P3^1;    //定义蜂鸣器端口
  27. sbit  ACC0 = ACC^0;
  28. sbit  ACC7 = ACC^7;


  29. /******************************************************************/
  30. /*                    延时函数声明                                */
  31. /******************************************************************/
  32. void mdelay(unsigned int t)
  33. {
  34.   unsigned char n;
  35. for(;t>0;t--)
  36. for(n=0;n<125;n++)
  37.   {;}
  38. }

  39. bit start;
  40. uchar str[7];

  41. //向LCD写入命令或数据************************************************************
  42. #define LCD_COMMAND                        0      // Command
  43. #define LCD_DATA                        1      // Data
  44. #define LCD_CLEAR_SCREEN        0x01      // 清屏
  45. #define LCD_HOMING                  0x02      // 光标返回原点

  46. //设置显示模式************************************************************
  47. #define LCD_SHOW                        0x04    //显示开
  48. #define LCD_HIDE                        0x00    //显示关         
  49. #define LCD_CURSOR                        0x02         //显示光标
  50. #define LCD_NO_CURSOR                0x00    //无光标                     
  51. #define LCD_FLASH                        0x01    //光标闪动
  52. #define LCD_NO_FLASH                0x00    //光标不闪动

  53. //设置输入模式************************************************************
  54. #define LCD_AC_UP                        0x02
  55. #define LCD_AC_DOWN                        0x00      // default
  56. #define LCD_MOVE                        0x01      // 画面可平移
  57. #define LCD_NO_MOVE                        0x00      //default

  58. unsigned char LCD_Wait(void);
  59. void LCD_Write(bit style, unsigned char input);

  60. /***********1602液晶显示部分子程序****************/
  61. void delay(uint z)          //延时函数
  62. {
  63.         uint x,y;
  64.         for(x=z;x>0;x--)
  65.                 for(y=110;y>0;y--);
  66. }

  67. void LCD_Write(bit style, unsigned char input)         
  68. {
  69.         LcdRs=style;
  70.         P0=input;
  71.         delay(5);
  72.         LcdEn=1;
  73.         delay(5);        
  74.         LcdEn=0;        
  75. }


  76. void LCD_SetDisplay(unsigned char DisplayMode)           //设置输出
  77. {
  78.         LCD_Write(LCD_COMMAND, 0x08|DisplayMode);        
  79. }



  80. void LCD_SetInput(unsigned char InputMode)          //设置输入
  81. {
  82.         LCD_Write(LCD_COMMAND, 0x04|InputMode);
  83. }


  84. void LCD_Initial()         //初始化LCD函数
  85. {
  86.         LcdEn=0;
  87.         LCD_Write(LCD_COMMAND,0x38);           //8位数据端口,2行显示,5*7点阵
  88.         LCD_Write(LCD_COMMAND,0x38);
  89.         LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);    //开启显示, 无光标
  90.         LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
  91.         LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);       //AC递增, 画面不动
  92. }


  93. void GotoXY(unsigned char x, unsigned char y)  //液晶字符输入的位置
  94. {
  95.         if(y==0)
  96.                 LCD_Write(LCD_COMMAND,0x80|x);
  97.         if(y==1)
  98.                 LCD_Write(LCD_COMMAND,0x80|(x-0x40));
  99. }


  100. void Print(unsigned char *str)        //将字符输出到液晶显示
  101. {
  102.         while(*str!='\0')
  103.         {
  104.                 LCD_Write(LCD_DATA,*str);
  105.                 str++;
  106.         }
  107. }


  108. void zhuanhuan(float a)//浮点数转换成字符串函数
  109. {         
  110.         memset(str,0,sizeof(str));
  111.         sprintf (str,"%f", a);
  112. }


  113. void welcome()         //初始界面函数
  114. {
  115.         LCD_Initial();
  116.         GotoXY(0,0);
  117.         Print("   Welcome!  ");
  118.         GotoXY(0,1);
  119.         Print("  Code of sht11 ");
  120.         delay(200);
  121. }


  122. void delay_n10us(uint n)  //延时n个10us@12M晶振
  123. {      
  124.         uint i;           
  125.         for(i=n;i>0;i--)   
  126.         {
  127.                 _nop_();_nop_();_nop_();
  128.                         _nop_();_nop_();_nop_();
  129.                 }
  130. }                                    

  131. /*********************第一部分LCD1602设置 END****************************************/


  132. /*********************第二部分SHT11设置   START**************************************/
  133. sbit SCK  = P1^0;      //定义通讯时钟端口
  134. sbit DATA = P1^1;      //定义通讯数据端口

  135. typedef union  
  136. { unsigned int i;      //定义了两个共用体
  137.   float f;
  138. } value;
  139. enum {TEMP,HUMI};      //TEMP=0,HUMI=1

  140. #define noACK 0             //用于判断是否结束通讯
  141. #define ACK   1             //结束数据传输
  142.                             //adr  command  r/w
  143. #define STATUS_REG_W 0x06   //000   0011    0
  144. #define STATUS_REG_R 0x07   //000   0011    1
  145. #define MEASURE_TEMP 0x03   //000   0001    1
  146. #define MEASURE_HUMI 0x05   //000   0010    1
  147. #define RESET        0x1e   //000   1111    0
  148. /****************定义函数****************/
  149. void s_transstart(void);               //启动传输函数
  150. void s_connectionreset(void);          //连接复位函数
  151. char s_write_byte(unsigned char value);//SHT11写函数
  152. char s_read_byte(unsigned char ack);   //SHT11读函数
  153. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);//测量温湿度函数
  154. void calc_dht90(float *p_humidity ,float *p_temperature);//温湿度补偿


  155. void s_transstart(void)  //启动传输函数
  156. // generates a transmission start  
  157. //       _____         ________
  158. // DATA:      |_______|
  159. //           ___     ___
  160. // SCK : ___|   |___|   |______
  161. {   
  162.    DATA=1; SCK=0;                   //Initial state
  163.    _nop_();
  164.    SCK=1;
  165.    _nop_();
  166.    DATA=0;
  167.    _nop_();
  168.    SCK=0;   
  169.    _nop_();_nop_();_nop_();
  170.    SCK=1;
  171.    _nop_();
  172.    DATA=1;        
  173.    _nop_();
  174.    SCK=0;        
  175. }


  176. void s_connectionreset(void)   //连接复位函数
  177. // communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
  178. //       _____________________________________________________         ________
  179. // DATA:                                                      |_______|
  180. //       _  _   _  _  _   _  _  _  _       ___    ___
  181. // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
  182. {   
  183.   unsigned char i;  
  184.   DATA=1; SCK=0;                    //Initial state
  185.   for(i=0;i<9;i++)                  //9 SCK cycles
  186.   {
  187.     SCK=1;
  188.     SCK=0;
  189.   }
  190.   s_transstart();                   //transmission start
  191. }


  192. char s_write_byte(unsigned char value)         // SHT11写字节函数
  193. //----------------------------------------------------------------------------------
  194. // writes a byte on the Sensibus and checks the acknowledge  
  195. {  
  196.   unsigned char i,error=0;   
  197.   for (i=0x80;i>0;i/=2)             //shift bit for masking
  198.   {  
  199.     if (i & value) DATA=1;          //masking value with i , write to SENSI-BUS
  200.     else DATA=0;                        
  201.     SCK=1;                          //clk for SENSI-BUS
  202.     _nop_();_nop_();_nop_();        //pulswith approx. 3 us     
  203.     SCK=0;
  204.   }
  205.   DATA=1;                           //release DATA-line
  206.   SCK=1;                            //clk #9 for ack  
  207.   error=DATA;                       //check ack (DATA will be pulled down by DHT90),DATA在第9个上升沿将被DHT90自动下拉为低电平。
  208.   _nop_();_nop_();_nop_();
  209.   SCK=0;
  210.   DATA=1;                           //release DATA-line
  211.   return error;                     //error=1 in case of no acknowledge //返回:0成功,1失败
  212. }


  213. /*****SHT11读函数   reads a byte form the Sensibus
  214. and gives an acknowledge in case of "ack=1"****/
  215. char s_read_byte(unsigned char ack)   
  216. {  
  217.   unsigned char i,val=0;
  218.   DATA=1;                           //release DATA-line
  219.   for (i=0x80;i>0;i/=2)             //shift bit for masking
  220.   { SCK=1;                          //clk for SENSI-BUS
  221.     if (DATA) val=(val | i);        //read bit   
  222.         _nop_();_nop_();_nop_();        //pulswith approx. 3 us
  223.     SCK=0;              
  224.   }
  225.   if(ack==1)DATA=0;                 //in case of "ack==1" pull down DATA-Line
  226.   else DATA=1;                      //如果是校验(ack==0),读取完后结束通讯
  227.   _nop_();_nop_();_nop_();          //pulswith approx. 3 us
  228.   SCK=1;                            //clk #9 for ack
  229.   _nop_();_nop_();_nop_();          //pulswith approx. 3 us  
  230.   SCK=0;                 
  231.   _nop_();_nop_();_nop_();          //pulswith approx. 3 us
  232.   DATA=1;                           //release DATA-line
  233.   return val;
  234. }


  235. /*  测量温湿度函数 makes a measurement
  236. (humidity/temperature) with checksum */
  237. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
  238. {  
  239.   unsigned error=0;
  240.   unsigned int i;

  241.   s_transstart();                   //transmission start
  242.   switch(mode){                     //send command to sensor
  243.     case TEMP  : error+=s_write_byte(MEASURE_TEMP); break;
  244.     case HUMI  : error+=s_write_byte(MEASURE_HUMI); break;
  245.     default     : break;   
  246.   }
  247.   for (i=0;i<65535;i++) if(DATA==0) break; //wait until sensor has finished the measurement
  248.   if(DATA) error+=1;                // or timeout (~2 sec.) is reached
  249.   *(p_value)  =s_read_byte(ACK);    //read the first byte (MSB)
  250.   *(p_value+1)=s_read_byte(ACK);    //read the second byte (LSB)
  251.   *p_checksum =s_read_byte(noACK);  //read checksum
  252.   return error;
  253. }


  254. void calc_sht90(float *p_humidity ,float *p_temperature)    //温湿度补偿函数
  255. // calculates temperature [C] and humidity [%RH]
  256. // input :  humi [Ticks] (12 bit)
  257. //          temp [Ticks] (14 bit)
  258. // output:  humi [%RH]
  259. //          temp [C]
  260. { const float C1=-4.0;              // for 12 Bit
  261.   const float C2=+0.0405;           // for 12 Bit
  262.   const float C3=-0.0000028;        // for 12 Bit
  263.   const float T1=+0.01;             // for 14 Bit @ 5V
  264.   const float T2=+0.00008;           // for 14 Bit @ 5V

  265.   float rh=*p_humidity;             // rh:      Humidity [Ticks] 12 Bit
  266.   float t=*p_temperature;           // t:       Temperature [Ticks] 14 Bit
  267.   float rh_lin;                     // rh_lin:  Humidity linear
  268.   float rh_true;                    // rh_true: Temperature compensated humidity
  269.   float t_C;                        // t_C   :  Temperature [C]

  270.   t_C=t*0.01 - 40;                  //calc. temperature from ticks to [C]
  271.   rh_lin=C3*rh*rh + C2*rh + C1;     //calc. humidity from ticks to [%RH]
  272.   rh_true=(t_C-25)*(T1+T2*rh)+rh_lin;   //calc. temperature compensated humidity [%RH]
  273.   if(rh_true>100)rh_true=100;       //cut if the value is outside of
  274.   if(rh_true<0.1)rh_true=0.1;       //the physical possible range

  275.   *p_temperature=t_C;               //return temperature [C]
  276.   *p_humidity=rh_true;              //return humidity[%RH]
  277. }
  278. /**************第二部分SHT11设置   END*****************************/



  279. /***************************主函数************************************/
  280. void main(void)
  281. {
  282.         int a,b;
  283.                 value humi_val,temp_val;
  284.         unsigned char error,checksum,i;
  285.             LcdRw=0;
  286.                 led1=0;
  287.                 led2=0;
  288.                 beep=1;
  289.                 start=0;
  290.        s_connectionreset();
  291.        welcome();//显示欢迎画面
  292.        delay(2000);
  293.                 LCD_Initial();
  294.         while(1)
  295.         { error=0;
  296.           error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);  
  297.           error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);  
  298.           if(error!=0)
  299.                    s_connectionreset();                 //in case of an error: connection reset
  300.           else
  301.           {
  302.                     humi_val.f=(float)humi_val.i;       //converts integer to float
  303.             temp_val.f=(float)temp_val.i;      //converts integer to float
  304.             calc_sht90(&humi_val.f,&temp_val.f);      //计算湿度与温度
  305.                          GotoXY(0,0);//
  306.                 Print("Tep:");
  307.                     GotoXY(0,1);
  308.                 Print("Hum:");
  309.                     zhuanhuan(temp_val.f);         //转换温度为uchar方便液晶显示
  310.                         GotoXY(5,0);
  311.                         str[5]=0xDF;//℃的符号
  312.                 str[6]=0x43;
  313.                         str[7]='\0';
  314.                 Print(str);
  315.                           if( temp_val.f>TEMPUP-1 || temp_val.f<TEMPDOWN-1 )
  316.                       {
  317.                                           //led1=1;
  318. //                                          beep=1;
  319.                                           a=1;
  320.                                           }  
  321.               else
  322.                    {
  323.                      //led1=0;  
  324. //                                          beep=0;
  325.                                           a=0 ;
  326.                                           }
  327.                         zhuanhuan(humi_val.f);//转换湿度为uchar方便液晶显示
  328.                     GotoXY(5,1);
  329.                         str[5]='%';//%的符号
  330.                 str[6]='\0';//字符串结束标志
  331.                  Print(str);
  332.                                 if( humi_val.f>HUMUP-1 || humi_val.f<HUMDOWN-1 )
  333. //                      {  led2=1;
  334. //                                                beep2=1;}  
  335.                        {  
  336.                                             //led2=1;
  337. //                                               beep=1;
  338.                                                         b=1;
  339.                                              }
  340.                    else
  341.                       {  
  342.                                           //led2=0;  
  343. //                                     beep=0;
  344.                         b=0;
  345.                                          }
  346.                                          if(a==1&&b==1)
  347.                                          {
  348.                                          led1=1;
  349.                                          led2=1;
  350.                                          beep=0;
  351.                                          }
  352.                                          else if(a==1&&b==0)
  353.                                          {
  354.                                          led1=1;
  355.                                          led2=0;
  356.                                          beep=0;
  357.                                          }
  358.                                          else if(a==0&&b==1)
  359.                                          {
  360.                                          led1=0;
  361.                                          led2=1;
  362.                                          beep=0;
  363.                                          }
  364.                                          else if(a==0&&b==0)
  365.                                          {
  366.                                          led1=0;
  367.                                          led2=0;
  368.                                          beep=1;
  369.                                          }
  370. //                      if(a==1||b==1)
  371. //                                          beep=1;
  372. //                                          else
  373. //                                          beep=0;
  374. //                                         a=b=0;
  375.                          }
  376.                  delay_n10us(80000);                                //延时约0.8s
  377.    }               
  378. }
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:82765 发表于 2017-5-15 20:22 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

板凳
ID:123289 发表于 2017-5-16 08:14 | 只看该作者
将一个点的测量程序,做成子程序,其参数只用传感器的端口号,每测一个端口(传感器)调用一次,不就OK了吗。
回复

使用道具 举报

地板
ID:196914 发表于 2017-5-16 08:27 | 只看该作者
cjjcjj1 发表于 2017-5-15 20:22
你好!温湿度测量,你想改成多少个点位呢

你好,三个传感器采集就好,请问该怎么改
回复

使用道具 举报

5#
ID:196914 发表于 2017-5-16 09:40 | 只看该作者
cjjcjj1 发表于 2017-5-15 20:22
你好!温湿度测量,你想改成多少个点位呢

三个传感器,就是不知道显示器该怎么改才能显示几组数据
回复

使用道具 举报

6#
ID:196914 发表于 2017-5-16 13:10 | 只看该作者
yzwzfyz 发表于 2017-5-16 08:14
将一个点的测量程序,做成子程序,其参数只用传感器的端口号,每测一个端口(传感器)调用一次,不就OK了吗 ...

可是那不就不能同时测量了吗?
回复

使用道具 举报

7#
ID:123289 发表于 2017-5-16 23:22 | 只看该作者
1、其一,采样命令可同时下,数据下载可以不同时,这时采样是同时的。
2、其二,温度是个惯性较大的东东,即使采样不同时,问题也不大,相对于单片机程序和速度,这点时差对结果影响不大。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表