找回密码
 立即注册

QQ登录

只需一步,快速开始

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

上位机显示并存储,RS485传输温湿度监控系统(SHT11传感器20个点位)

  [复制链接]
跳转到指定楼层
楼主
实现功能
1、温湿度实时检测
2、20个点位RS485传输
3、上位机显示20个点位数据
4、上位机对每个点位数据同步保存

器件介绍
1、温湿度传感器 SHT11








2、RS485芯片




制作完成的实物






上位机读取数据界面


温湿度资料下载
       温湿度传感器SHT11数据手册.pdf (1.44 MB, 下载次数: 42)

485通讯芯片资料下载
       DS75176.pdf (941.27 KB, 下载次数: 52)

SHT11液晶显示源程序
       SHT11液晶显示源程序.rar (3.23 KB, 下载次数: 73)

  1. /***********************************************************************************

  2. ;功能说明:SHT11与LCD1602的温湿度显示
  3. ;文件名称:SHT11.c   

  4. ;***********************************************************************************/

  5. /*************定义接口********************
  6.          P0------DB0~DB7  (LCD1602)     
  7.          P2.0------RS      (LCD1602)
  8.          P2.1------RW      (LCD1602)
  9.          P2.2------E       (LCD1602)
  10.          P2.6------SCK     (SHT11)
  11.          P2.7------DATA    (SHT11)
  12. *****************************************/

  13. #include <reg52.h>
  14. #include <intrins.h>
  15. #include <math.h>
  16. #include <stdio.h>

  17. //第一部分LCD1602设置
  18. #define LCD_DB  P0
  19. sbit    LCD_RS=P2^0;
  20. sbit    LCD_RW=P2^1;
  21. sbit    LCD_E=P2^2;

  22. /******定义函数****************/
  23. #define uchar unsigned char
  24. #define uint unsigned int
  25. void LCD_init(void);                          //初始化函数
  26. void LCD_write_command(uchar command);        //写指令函数
  27. void LCD_write_data(uchar dat);               //写数据函数
  28. void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2)
  29. void LCD_disp_str(uchar x,uchar y,uchar *str); //LCD1602显示字符串函数
  30. void delay_n10us(uint n);                     //延时函数

  31. /*--------------------------------------
  32. ;模块名称:LCD_init();
  33. ;功    能:初始化LCD1602
  34. ;-------------------------------------*/
  35. void LCD_init(void)
  36. {
  37. delay_n10us(10);
  38. LCD_write_command(0x38);//设置8位格式,2行,5x7
  39. delay_n10us(10);
  40. LCD_write_command(0x0c);//整体显示,关光标,不闪烁
  41. delay_n10us(10);
  42. LCD_write_command(0x06);//设定输入方式,增量不移位
  43. delay_n10us(10);
  44. LCD_write_command(0x01);//清除屏幕显示
  45. delay_n10us(100);       //延时清屏,延时函数,延时约n个10us
  46. }


  47. /*--------------------------------------
  48. ;模块名称:LCD_write_command();
  49. ;功    能:LCD1602写指令函数
  50. ;-------------------------------------*/
  51. void LCD_write_command(uchar dat)
  52. {
  53. delay_n10us(10);
  54. LCD_RS=0;         //指令
  55. LCD_RW=0;         //写入
  56. LCD_E=1;          //允许
  57. LCD_DB=dat;
  58. delay_n10us(10);  //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
  59. LCD_E=0;
  60. delay_n10us(10);  //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
  61. }


  62. /*--------------------------------------
  63. ;模块名称:LCD_write_data();
  64. ;功    能:LCD1602写数据函数
  65. ;-------------------------------------*/
  66. void LCD_write_data(uchar dat)
  67. {
  68. delay_n10us(10);
  69. LCD_RS=1;          //数据
  70. LCD_RW=0;          //写入
  71. LCD_E=1;           //允许
  72. LCD_DB=dat;
  73. delay_n10us(10);
  74. LCD_E=0;
  75. delay_n10us(10);
  76. }

  77. /*--------------------------------------
  78. ;模块名称:LCD_disp_char();
  79. ;功    能:LCD1602显示一个字符函数
  80. ;-------------------------------------*/
  81. void LCD_disp_char(uchar x,uchar y,uchar dat)
  82. {
  83.   uchar address;
  84.   if(y==1)
  85.          address=0x80+x;
  86.   else
  87.          address=0xc0+x;
  88.   LCD_write_command(address);
  89.   LCD_write_data(dat);
  90. }



  91. /*--------------------------------------
  92. ;模块名称:LCD_disp_str();
  93. ;功    能:LCD1602显示字符串
  94. ;-------------------------------------*/
  95. void LCD_disp_str(uchar x,uchar y,uchar *str)
  96. {
  97.   uchar address;
  98.   if(y==1)
  99.          address=0x80+x;
  100.   else
  101.          address=0xc0+x;
  102.   LCD_write_command(address);
  103.   while(*str!='\0')
  104.   {
  105.     LCD_write_data(*str);   
  106.     str++;
  107.   }
  108. }

  109. /*--------------------------------------
  110. ;模块名称:delay_n10us();
  111. ;功    能:延时函数,延时约n个10us
  112. ;-------------------------------------*/
  113. void delay_n10us(uint n)  //延时n个10us@12M晶振
  114. {      
  115.         uint i;           
  116.         for(i=n;i>0;i--)   
  117.         {
  118.         _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  119.                 }
  120. }                                    
  121. //第二部分SHT11设置
  122. sbit SCK  = P2^6;      //定义通讯时钟端口
  123. sbit DATA = P2^7;      //定义通讯数据端口

  124. typedef union  
  125. { unsigned int i;      //定义了两个共用体
  126.   float f;
  127. } value;

  128. enum {TEMP,HUMI};      //TEMP=0,HUMI=1


  129. #define noACK 0             //用于判断是否结束通讯
  130. #define ACK   1             //结束数据传输
  131.                             //adr  command  r/w
  132. #define STATUS_REG_W 0x06   //000   0011    0
  133. #define STATUS_REG_R 0x07   //000   0011    1
  134. #define MEASURE_TEMP 0x03   //000   0001    1
  135. #define MEASURE_HUMI 0x05   //000   0010    1
  136. #define RESET        0x1e   //000   1111    0

  137. /****************定义函数****************/
  138. void s_transstart(void);               //启动传输函数
  139. void s_connectionreset(void);          //连接复位函数
  140. char s_write_byte(unsigned char value);//SHT11写函数
  141. char s_read_byte(unsigned char ack);   //SHT11读函数
  142. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode);//测量温湿度函数
  143. void calc_SHT11(float *p_humidity ,float *p_temperature);//温湿度补偿

  144. /*--------------------------------------
  145. ;模块名称:s_transstart();
  146. ;功    能:启动传输函数
  147. ;-------------------------------------*/  
  148. void s_transstart(void)
  149. {   
  150.    DATA=1; SCK=0;                   //Initial state
  151.    _nop_();
  152.    SCK=1;
  153.    _nop_();
  154.    DATA=0;
  155.    _nop_();
  156.    SCK=0;   
  157.    _nop_();_nop_();_nop_();
  158.    SCK=1;
  159.    _nop_();
  160.    DATA=1;        
  161.    _nop_();
  162.    SCK=0;        
  163. }

  164. /*--------------------------------------
  165. ;模块名称:s_connectionreset();
  166. ;功    能:连接复位函数
  167. ;-------------------------------------*/
  168. void s_connectionreset(void)
  169. {   
  170.   unsigned char i;  
  171.   DATA=1; SCK=0;                    //Initial state
  172.   for(i=0;i<9;i++)                  //9 SCK cycles
  173.   {
  174.     SCK=1;
  175.     SCK=0;
  176.   }
  177.   s_transstart();                   //transmission start
  178. }

  179. /*--------------------------------------
  180. ;模块名称:s_write_byte();
  181. ;功    能:SHT11写函数
  182. ;-------------------------------------*/
  183. char s_write_byte(unsigned char value)
  184. //----------------------------------------------------------------------------------
  185. {  
  186.   unsigned char i,error=0;   
  187.   for (i=0x80;i>0;i/=2)             //shift bit for masking
  188.   {  
  189.     if (i & value) DATA=1;          //masking value with i , write to SENSI-BUS
  190.     else DATA=0;                        
  191.     SCK=1;                          //clk for SENSI-BUS
  192.     _nop_();_nop_();_nop_();        //pulswith approx. 3 us     
  193.     SCK=0;
  194.   }
  195.   DATA=1;                           //release DATA-line
  196.   SCK=1;                            //clk #9 for ack  
  197.   error=DATA;                       //check ack (DATA will be pulled down by SHT11),DATA在第9个上升沿将被SHT11自动下拉为低电平。
  198.   _nop_();_nop_();_nop_();
  199.   SCK=0;
  200.   DATA=1;                           //release DATA-line
  201.   return error;                     //error=1 in case of no acknowledge //返回:0成功,1失败
  202. }


  203. /*--------------------------------------
  204. ;模块名称:s_read_byte();
  205. ;功    能:DHT11读函数
  206. ;-------------------------------------*/
  207. char s_read_byte(unsigned char ack)  
  208. // reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"  
  209. {  
  210.   unsigned char i,val=0;
  211.   DATA=1;                           //release DATA-line
  212.   for (i=0x80;i>0;i/=2)             //shift bit for masking
  213.   { SCK=1;                          //clk for SENSI-BUS
  214.     if (DATA) val=(val | i);        //read bit   
  215.         _nop_();_nop_();_nop_();        //pulswith approx. 3 us
  216.     SCK=0;              
  217.   }
  218.   if(ack==1)DATA=0;                 //in case of "ack==1" pull down DATA-Line
  219.   else DATA=1;                      //如果是校验(ack==0),读取完后结束通讯
  220.   _nop_();_nop_();_nop_();          //pulswith approx. 3 us
  221.   SCK=1;                            //clk #9 for ack
  222.   _nop_();_nop_();_nop_();          //pulswith approx. 3 us  
  223.   SCK=0;                 
  224.   _nop_();_nop_();_nop_();          //pulswith approx. 3 us
  225.   DATA=1;                           //release DATA-line
  226.   return val;
  227. }

  228. /*--------------------------------------
  229. ;模块名称:s_measure();
  230. ;功    能:测量温湿度函数
  231. ;-------------------------------------*/
  232. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
  233. // makes a measurement (humidity/temperature) with checksum
  234. {  
  235.   unsigned error=0;
  236.   unsigned int i;

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

  250. /*--------------------------------------
  251. ;模块名称:calc_SHT11();
  252. ;功    能:温湿度补偿函数
  253. ;-------------------------------------*/
  254. void calc_SHT11(float *p_humidity ,float *p_temperature)
  255. { const float C1=-4.0;              // for 12 Bit
  256.   const float C2=+0.0405;           // for 12 Bit
  257.   const float C3=-0.0000028;        // for 12 Bit
  258.   const float T1=+0.01;             // for 14 Bit @ 5V
  259.   const float T2=+0.00008;           // for 14 Bit @ 5V

  260.   float rh=*p_humidity;             // rh:      Humidity [Ticks] 12 Bit
  261.   float t=*p_temperature;           // t:       Temperature [Ticks] 14 Bit
  262.   float rh_lin;                     // rh_lin:  Humidity linear
  263.   float rh_true;                    // rh_true: Temperature compensated humidity
  264.   float t_C;                        // t_C   :  Temperature [C]

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

  270.   *p_temperature=t_C;               //return temperature [C]
  271.   *p_humidity=rh_true;              //return humidity[%RH]
  272. }

  273. //*********主函数*****************
  274. void main(void)
  275. {
  276.         value humi_val,temp_val;
  277.         unsigned char error,checksum;
  278.         unsigned int wendu,shidu;
  279.         LCD_init();        
  280.         s_connectionreset();
  281.         LCD_disp_str(0,1,"TE");
  282.         LCD_disp_str(0,2,"RH");

  283.         LCD_disp_str(2,1,"T");
  284.         LCD_disp_str(2,2,"R");

  285.         while(1)
  286.         {
  287.                   error=0;
  288.           error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);  //measure humidity
  289.           error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);  //measure temperature
  290.           if(error!=0) s_connectionreset();                 //in case of an error: connection reset
  291.           else
  292.           {
  293.                     humi_val.f=(float)humi_val.i;                   //converts integer to float
  294.             temp_val.f=(float)temp_val.i;                   //converts integer to float
  295.             calc_SHT11(&humi_val.f,&temp_val.f);            //calculate humidity, temperature
  296.             wendu=10*temp_val.f;
  297.             LCD_disp_char(2,1,wendu/1000+'0');              //显示温度百位
  298.             LCD_disp_char(3,1,(wendu%1000)/100+'0');        //显示温度十位
  299.             LCD_disp_char(4,1,(wendu%100)/10+'0');          //显示温度个位
  300.             LCD_disp_char(6,1,(wendu%10)+'0');              //显示温度小数点后第一位

  301.             shidu=10*humi_val.f;
  302.             LCD_disp_char(2,2,shidu/1000+'0');               //显示湿度百位
  303.             LCD_disp_char(3,2,(shidu%1000)/100+'0');         //显示湿度十位
  304.             LCD_disp_char(4,2,(shidu%100)/10+'0');           //显示湿度个位
  305.             LCD_disp_char(6,2,(shidu%10)+'0');               //显示湿度小数点后第一位
  306.           }
  307.         }
  308. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏11 分享淘帖 顶3 踩
回复

使用道具 举报

沙发
ID:639650 发表于 2019-11-12 09:39 | 只看该作者
有上位机和下位机通过RS485协议进行温湿度数据传输的代码吗?
回复

使用道具 举报

板凳
ID:543942 发表于 2019-12-21 15:51 | 只看该作者
能分享上位机读取数据界面的软件吗
回复

使用道具 举报

地板
ID:617449 发表于 2019-12-21 16:57 | 只看该作者
asdlkj12310 发表于 2019-12-21 15:51
能分享上位机读取数据界面的软件吗

你好!多点温湿度上位机执行文件 多点温湿度监控上位机.rar (1.09 MB, 下载次数: 80)


回复

使用道具 举报

5#
ID:214276 发表于 2020-3-18 17:14 | 只看该作者
每块温湿度板的下位机地址是如何实现设定的呢。有没有传输代码呢。
回复

使用道具 举报

6#
ID:617449 发表于 2020-3-22 18:09 | 只看该作者
chinarenxx 发表于 2020-3-18 17:14
每块温湿度板的下位机地址是如何实现设定的呢。有没有传输代码呢。

你好!
下位机控制板的地址,靠拨码开关来设置;



本设计可以按照具体需求做相应的软硬件修改
回复

使用道具 举报

7#
ID:560110 发表于 2020-8-15 23:37 | 只看该作者
zsm6601 发表于 2019-11-12 09:39
有上位机和下位机通过RS485协议进行温湿度数据传输的代码吗?

你那有程序了吗
回复

使用道具 举报

8#
ID:847662 发表于 2022-4-13 12:31 | 只看该作者
电路图能分享下吗楼主
回复

使用道具 举报

9#
ID:617449 发表于 2022-4-13 12:59 | 只看该作者

需要程序或原理图都可以
回复

使用道具 举报

10#
ID:847662 发表于 2022-4-13 13:29 | 只看该作者
还有电路图能分享下吗楼主
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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