找回密码
 立即注册

QQ登录

只需一步,快速开始

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

SHT11数字温湿度传感器 含源代码和仿真图

  [复制链接]
跳转到指定楼层
楼主
分享一个SHT11-数字温湿度传感器,含源代码和仿真图


单片机源程序如下:
  1. #include <reg52.h>  
  2. #include <intrins.h>  
  3. #include "LCD1602.h"
  4. /********************************************************
  5. 宏定义
  6. ********************************************************/
  7. #define uint unsigned int  
  8. #define uchar unsigned char  
  9. #define noACK 0
  10. #define ACK   1
  11. #define STATUS_REG_W 0x06
  12. #define STATUS_REG_R 0x07
  13. #define MEASURE_TEMP 0x03
  14. #define MEASURE_HUMI 0x05
  15. #define RESET        0x1e

  16. enum { TEMP, HUMI };

  17. typedef union               //定义共用同类型  
  18. {
  19.         unsigned int i;
  20.         float f;
  21. } value;


  22. /********************************************************
  23. 位定义
  24. ********************************************************/
  25. sbit SCK = P1 ^ 0;
  26. sbit DATA = P1 ^ 1;

  27. /********************************************************
  28. 变量定义
  29. ********************************************************/
  30. uchar wendu[6];
  31. uchar shidu[6];


  32. /********************************************************
  33. 50us延时函数
  34. ********************************************************/
  35. void delay_50us(uint t)
  36. {
  37.         uint j;
  38.         for (; t>0; t--)
  39.         for (j = 19; j>0; j--);
  40. }


  41. /*******************************************************
  42. 液晶显示函数
  43. ********************************************************/
  44. void displaywendu(void)
  45. {
  46.         uchar i;
  47.         write_com(0x80+0x40);
  48.         write_data('T');
  49.         write_data(':');
  50.         for (i = 0; i<3; i++)
  51.         {
  52.                 write_data(wendu[i]);
  53.                 delay_50us(1);
  54.         }
  55.         for (i = 0; i<1; i++)
  56.         {
  57.                 write_data('.');
  58.                 delay_50us(1);
  59.         }
  60.         for (i = 4; i<5; i++)
  61.         {
  62.                 write_data(wendu[i]);
  63.                 delay_50us(1);
  64.         }
  65.         write_data(0xDF);
  66.         write_data('C');
  67. }


  68. /********************************************************
  69. 液晶显示函数
  70. ********************************************************/
  71. void displayshidu(void)
  72. {
  73.         uchar i;
  74.         write_com(0x80);
  75.         write_data('H');
  76.         write_data(':');
  77.         for (i = 0; i<3; i++)
  78.         {
  79.                 write_data(shidu[i]);
  80.                 delay_50us(1);
  81.         }
  82.         for (i = 0; i<1; i++)
  83.         {
  84.                 write_data('.');
  85.                 delay_50us(1);
  86.         }
  87.         for (i = 4; i<5; i++)
  88.         {
  89.                 write_data(shidu[i]);
  90.                 delay_50us(1);
  91.         }
  92.         write_data('%');
  93.         write_data('R');
  94.         write_data('H');
  95. }

  96. /********************************************************
  97. SHT11写字节程序
  98. ********************************************************/
  99. char s_write_byte(unsigned char value)
  100. {
  101.         unsigned char i, error = 0;
  102.         for (i = 0x80; i>0; i >>= 1)             //高位为1,循环右移  
  103.         {
  104.                 if (i&value) DATA = 1;          //和要发送的数相与,结果为发送的位  
  105.                 else DATA = 0;
  106.                 SCK = 1;
  107.                 _nop_(); _nop_(); _nop_();        //延时3us   
  108.                 SCK = 0;
  109.         }
  110.         DATA = 1;                           //释放数据线  
  111.         SCK = 1;
  112.         error = DATA;                       //检查应答信号,确认通讯正常  
  113.         _nop_(); _nop_(); _nop_();
  114.         SCK = 0;
  115.         DATA = 1;
  116.         return error;                     //error=1 通讯错误  
  117. }

  118. /********************************************************
  119. SHT11读字节程序
  120. ********************************************************/
  121. char s_read_byte(unsigned char ack)
  122. {
  123.         unsigned char i, val = 0;
  124.         DATA = 1;                           //释放数据线  
  125.         for (i = 0x80; i>0; i >>= 1)             //高位为1,循环右移  
  126.         {
  127.                 SCK = 1;
  128.                 if (DATA) val = (val | i);             //读一位数据线的值   
  129.                 SCK = 0;
  130.         }
  131.         DATA = !ack;                        //如果是校验,读取完后结束通讯;  
  132.         SCK = 1;
  133.         _nop_(); _nop_(); _nop_();          //延时3us   
  134.         SCK = 0;
  135.         _nop_(); _nop_(); _nop_();
  136.         DATA = 1;                           //释放数据线  
  137.         return val;
  138. }

  139. /********************************************************
  140. SHT11启动传输
  141. ********************************************************/
  142. void s_transstart(void)
  143. {
  144.         DATA = 1; SCK = 0;                   //准备  
  145.         _nop_();
  146.         SCK = 1;
  147.         _nop_();
  148.         DATA = 0;
  149.         _nop_();
  150.         SCK = 0;
  151.         _nop_(); _nop_(); _nop_();
  152.         SCK = 1;
  153.         _nop_();
  154.         DATA = 1;
  155.         _nop_();
  156.         SCK = 0;
  157. }


  158. /********************************************************
  159. SHT11连接复位
  160. ********************************************************/
  161. void s_connectionreset(void)
  162. {
  163.         unsigned char i;
  164.         DATA = 1; SCK = 0;                    //准备  
  165.         for (i = 0; i<9; i++)                  //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位  
  166.         {
  167.                 SCK = 1;
  168.                 SCK = 0;
  169.         }
  170.         s_transstart();                   //启动传输  
  171. }

  172. /********************************************************
  173. SHT11温湿度检测
  174. ********************************************************/
  175. char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
  176. {
  177.         unsigned error = 0;
  178.         unsigned int i;

  179.         s_transstart();                   //启动传输  
  180.         switch (mode)                      //选择发送命令  
  181.         {
  182.         case TEMP: error += s_write_byte(MEASURE_TEMP); break;          //测量温度  
  183.         case HUMI: error += s_write_byte(MEASURE_HUMI); break;          //测量湿度  
  184.         default: break;
  185.         }
  186.         for (i = 0; i<65535; i++) if (DATA == 0) break;        //等待测量结束  
  187.         if (DATA) error += 1;                              // 如果长时间数据线没有拉低,说明测量错误   
  188.         *(p_value) = s_read_byte(ACK);           //读第一个字节,高字节 (MSB)  
  189.         *(p_value + 1) = s_read_byte(ACK);          //读第二个字节,低字节 (LSB)  
  190.         *p_checksum = s_read_byte(noACK);        //read CRC校验码  
  191.         return error;                   // error=1 通讯错误  
  192. }
  193. /********************************************************
  194. SHT11温湿度值标度变换及温度补偿
  195. ********************************************************/
  196. void calc_sth10(float *p_humidity, float *p_temperature)
  197. {
  198.         const float C1 = -4.0;              // 12位湿度精度 修正公式  
  199.         const float C2 = +0.0405;           // 12位湿度精度 修正公式  
  200.         const float C3 = -0.0000028;        // 12位湿度精度 修正公式  
  201.         const float T1 = +0.01;             // 14位温度精度 5V条件  修正公式  
  202.         const float T2 = +0.00008;          // 14位温度精度 5V条件  修正公式  

  203.         float rh = *p_humidity;             // rh:      12位 湿度   
  204.         float t = *p_temperature;           // t:       14位 温度  
  205.         float rh_lin;                     // rh_lin: 湿度 linear值  
  206.         float rh_true;                    // rh_true: 湿度 ture值  
  207.         float t_C;                        // t_C   : 温度 ℃  

  208.         t_C = t*0.01 - 40;                  //补偿温度  
  209.         rh_lin = C3*rh*rh + C2*rh + C1;     //相对湿度非线性补偿  
  210.         rh_true = (t_C - 25)*(T1 + T2*rh) + rh_lin;   //相对湿度对于温度依赖性补偿  
  211.         if (rh_true>100)rh_true = 100;       //湿度最大修正  
  212.         if (rh_true<0.1)rh_true = 0.1;       //湿度最小修正  

  213.         *p_temperature = t_C;               //返回温度结果  
  214.         *p_humidity = rh_true;              //返回湿度结果  
  215. }
  216. /********************************************************
  217. 主函数
  218. ********************************************************/
  219. void main(void)
  220. {
  221.         unsigned int temp, humi;
  222.         value humi_val, temp_val;        //定义两个共同体,一个用于湿度,一个用于温度  
  223.         unsigned char error;            //用于检验是否出现错误  
  224.         unsigned char checksum;         //CRC   
  225.         LcdInitiate();
  226. ……………………

  227. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
SHT11-数字温湿度传感器只支持Proteus7.5版本.7z (37.17 KB, 下载次数: 368)


评分

参与人数 2黑币 +51 收起 理由
zfk + 1 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:208180 发表于 2017-11-17 15:27 | 只看该作者
想咨询一下,如果温度在零下的话,源码应该如何修改才能让lcd顺利显示出负数?
回复

使用道具 举报

板凳
ID:250456 发表于 2017-11-17 16:16 | 只看该作者
顶,好文
回复

使用道具 举报

地板
ID:675478 发表于 2019-12-27 15:38 | 只看该作者
很有用
回复

使用道具 举报

5#
ID:316621 发表于 2020-4-12 21:08 | 只看该作者
老哥 我打开之后显示 “新文件设计”,求帮助
回复

使用道具 举报

6#
ID:733782 发表于 2020-4-22 09:53 | 只看该作者
感谢分享,值得学习。
回复

使用道具 举报

7#
ID:676143 发表于 2020-4-24 18:21 来自手机 | 只看该作者
etxuxu 发表于 2017-11-17 15:27
想咨询一下,如果温度在零下的话,源码应该如何修改才能让lcd顺利显示出负数?

你好,显示零下温度需要怎样修改呢
回复

使用道具 举报

8#
ID:767820 发表于 2020-6-2 20:12 | 只看该作者
感谢楼主的分享
回复

使用道具 举报

9#
ID:773585 发表于 2020-6-9 09:17 | 只看该作者
很棒,很详细
回复

使用道具 举报

10#
ID:786360 发表于 2020-6-22 14:55 | 只看该作者
有代码吗可以私发给我吗
回复

使用道具 举报

11#
ID:842307 发表于 2021-2-18 22:38 | 只看该作者
SHT11没有ACK回复是什么原因,使用proteus仿真,没有ACK回复
回复

使用道具 举报

12#
ID:923241 发表于 2021-5-18 13:59 | 只看该作者
有仿真图和代码吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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