找回密码
 立即注册

QQ登录

只需一步,快速开始

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

[转载]单片机+DHT11温湿度+1602液晶显示

[复制链接]
跳转到指定楼层
楼主
ID:639106 发表于 2020-7-19 17:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
这资料蛮好的,拿出来分享......仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uchar unsigned char         //宏定义方便以后用
  4. #define uint unsigned int  
  5. #define ulong unsigned long

  6. //SHT11接口
  7. sbit DATA = P2^5;
  8. sbit SCK = P2^4;

  9. typedef union                   //定义共同类型
  10. {
  11.   unsigned int i;           //i表示测量得到的温湿度数据(int 形式保存的数据)
  12.   float f;                           //f表示测量得到的温湿度数据(float 形式保存的数据)
  13. } value;

  14. enum {TEMP,HUMI};

  15. uchar TEMP_BUF[7];                                         //用于记录温度
  16. uchar HUMI_BUF[5];                                         //用于记录湿度

  17. int real_tempure=0;                //实际温度
  18. uchar real_humi=0;


  19. //LCD port
  20. sbit LcdRs= P2^0;
  21. sbit LcdRw= P2^1;
  22. sbit LcdEn= P2^2;
  23. sfr  DBPort= 0x80;                //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口


  24. //向LCD写入命令或数据************************************************************
  25. #define LCD_COMMAND                        0      // Command
  26. #define LCD_DATA                        1      // Data
  27. #define LCD_CLEAR_SCREEN        0x01      // 清屏
  28. #define LCD_HOMING                  0x02      // 光标返回原点


  29. //设置显示模式************************************************************
  30. #define LCD_SHOW                        0x04    //显示开
  31. #define LCD_HIDE                        0x00    //显示关          

  32. #define LCD_CURSOR                        0x02         //显示光标
  33. #define LCD_NO_CURSOR                0x00    //无光标                     

  34. #define LCD_FLASH                        0x01    //光标闪动
  35. #define LCD_NO_FLASH                0x00    //光标不闪动
  36. //内部等待函数**************************************************************************
  37. unsigned char LCD_Wait(void)
  38. {
  39.         LcdRs=0;
  40.         LcdRw=1;        _nop_();
  41.         LcdEn=1;        _nop_();
  42.         _nop_();
  43.         _nop_();
  44.         _nop_();
  45.         LcdEn=0;
  46.         return DBPort;               
  47. }

  48. void LCD_Write(bit style, unsigned char input)
  49. {
  50.         LcdEn=0;
  51.         LcdRs=style;
  52.         LcdRw=0;                _nop_();
  53.         DBPort=input;        _nop_();//注意顺序
  54.         LcdEn=1;                _nop_();//注意顺序
  55.         LcdEn=0;                _nop_();
  56.         LCD_Wait();       
  57. }

  58. void LCD_SetDisplay(unsigned char DisplayMode)
  59. {
  60.         LCD_Write(LCD_COMMAND, 0x08|DisplayMode);       
  61. }

  62. //设置输入模式************************************************************
  63. #define LCD_AC_UP                        0x02
  64. #define LCD_AC_DOWN                        0x00      // default

  65. #define LCD_MOVE                        0x01      // 画面可平移
  66. #define LCD_NO_MOVE                        0x00      //default

  67. void LCD_SetInput(unsigned char InputMode)
  68. {
  69.         LCD_Write(LCD_COMMAND, 0x04|InputMode);
  70. }


  71. //初始化LCD************************************************************
  72. void LCD_Initial()
  73. {
  74.         LcdEn=0;
  75.         LCD_Write(LCD_COMMAND,0x38);           //8位数据端口,2行显示,5*7点阵
  76.         LCD_Write(LCD_COMMAND,0x38);
  77.         LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);    //开启显示, 无光标
  78.         LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏
  79.         LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);       //AC递增, 画面不动
  80. }

  81. //************************************************************************
  82. void GotoXY(unsigned char x, unsigned char y)
  83. {
  84.         if(y==0)
  85.                 LCD_Write(LCD_COMMAND,0x80|x);
  86.         if(y==1)
  87.                 LCD_Write(LCD_COMMAND,0x80|(x-0x40));
  88. }

  89. void Print(unsigned char *str)         //在LCD上显示数据,内部调用
  90. {
  91.         while(*str!='\0')
  92.         {
  93.                 LCD_Write(LCD_DATA,*str);
  94.                 str++;
  95.         }
  96. }

  97. void LCD_Print(unsigned char x, unsigned char y, unsigned char *str) //指定的位置打印指定数据
  98. {
  99.   GotoXY(x,y);
  100.   Print(str);
  101. }

  102. /********************************************************************
  103. * 名称 : Delay_1ms()
  104. * 功能 : 延时子程序
  105. * 输入 : x
  106. * 输出 : 无
  107. ***********************************************************************/
  108. void Delay(uint i)//延时
  109. {
  110.         uint x,j;
  111.         for(j=0;j<i;j++)
  112.         for(x=0;x<=148;x++);       
  113. }


  114. /***********************************************************************************************************************************************************/

  115. //SHT11程序


  116. #define noACK 0                                //继续传输数据,用于判断是否结束通讯
  117. #define ACK   1             //结束数据传输;
  118.                                                         //地址  命令  读/写
  119. #define STATUS_REG_W 0x06   //000   0011    0
  120. #define STATUS_REG_R 0x07   //000   0011    1
  121. #define MEASURE_TEMP 0x03   //000   0001    1
  122. #define MEASURE_HUMI 0x05   //000   0010    1
  123. #define RESET        0x1e   //000   1111    0


  124. //写字节程序
  125. char SHTXX_write_byte(unsigned char value)   
  126. {
  127.         unsigned char i,error=0;
  128.         for (i=0x80;i>0;i/=2)             //shift bit for masking 高位为1,循环右移
  129.         {
  130.                 if (i&value) DATA=1;          //和要发送的数相与,结果为发送的位
  131.             else DATA=0;                        
  132.             SCK=1;                          
  133.             _nop_();_nop_();_nop_();        //延时3us
  134.             SCK=0;
  135.         }
  136.         DATA=1;                           //释放数据线
  137.         SCK=1;                           
  138.         error=DATA;                       //检查应答信号,确认通讯正常
  139.         _nop_();_nop_();_nop_();
  140.         SCK=0;        
  141.         DATA=1;
  142.         return error;                     //error=1 通讯错误
  143. }

  144. //读字节程序
  145. char SHTXX_read_byte(unsigned char ack)
  146. //----------------------------------------------------------------------------------
  147. {
  148.         unsigned char i,val=0;
  149.         DATA=1;                           //释放数据线
  150.         for(i=0x80;i>0;i>>=1)             //高位为1,循环右移
  151.         {
  152.                 SCK=1;                        
  153.             if(DATA) val=(val|i);        //读一位数据线的值
  154.             SCK=0;      
  155.         }
  156.         DATA=!ack;                        //如果是校验,读取完后结束通讯;
  157.         SCK=1;                           
  158.         _nop_();_nop_();_nop_();          //延时3us
  159.         SCK=0;   
  160.         _nop_();_nop_();_nop_();      
  161.         DATA=1;                           //释放数据线
  162.         return val;
  163. }

  164. //启动传输
  165. void SHTXX_transstart(void)
  166. // generates a transmission start
  167. //       _____         ________
  168. // DATA:      |_______|
  169. //           ___     ___
  170. // SCK : ___|   |___|   |______
  171. {
  172.            DATA=1; SCK=0;                   //准备
  173.            _nop_();
  174.           SCK=1;
  175.            _nop_();
  176.            DATA=0;
  177.            _nop_();
  178.           SCK=0;
  179.            _nop_();_nop_();_nop_();
  180.            SCK=1;
  181.            _nop_();
  182.           DATA=1;     
  183.           _nop_();
  184.            SCK=0;     
  185. }


  186. //连接复位
  187. void SHTXX_Init(void)
  188. // communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
  189. //       _____________________________________________________         ________
  190. // DATA:                                                      |_______|
  191. //          _    _    _    _    _    _    _    _    _        ___     ___
  192. // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______
  193. {
  194.         unsigned char i;
  195.         DATA=1; SCK=0;                    //准备
  196.         for(i=0;i<9;i++)                  //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位
  197.         {
  198.                 SCK=1;
  199.             SCK=0;
  200.         }
  201.         SHTXX_transstart();                   //启动传输
  202. }

  203. /*
  204. //软复位程序
  205. char SHTXX_softreset(void)
  206. // resets the sensor by a softreset
  207. {
  208.         unsigned char error=0;
  209.         SHTXX_Init();              //启动连接复位
  210.         error+=SHTXX_write_byte(RESET);       //发送复位命令
  211.         return error;                     //error=1 通讯错误
  212. }
  213.   */


  214.            
  215. //温湿度测量
  216. char SHTXX_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
  217. // 进行温度或者湿度转换,由参数mode决定转换内容;
  218. {
  219. //        enum {TEMP,HUMI};                 //已经在头文件中定义
  220.         unsigned error=0;
  221.         unsigned int i;

  222.         SHTXX_transstart();                   //启动传输
  223.         switch(mode)                     //选择发送命令
  224.     {       
  225.                 case TEMP : error+=SHTXX_write_byte(MEASURE_TEMP); break;                   //测量温度
  226.             case HUMI : error+=SHTXX_write_byte(MEASURE_HUMI); break;                   //测量湿度
  227.             default     : break;
  228.         }
  229.         for (i=0;i<65535;i++) if(DATA==0) break; //等待测量结束
  230.         if(DATA) error+=1;                // 如果长时间数据线没有拉低,说明测量错误
  231.         *(p_value) =SHTXX_read_byte(ACK);    //读第一个字节,高字节 (MSB)
  232.         *(p_value+1)=SHTXX_read_byte(ACK);    //读第二个字节,低字节 (LSB)
  233.         *p_checksum =SHTXX_read_byte(noACK); //read CRC校验码
  234.         return error;                                         // error=1 通讯错误
  235. }

  236. //温湿度值标度变换及温度补偿
  237. void SHTXX_calc(float *p_humidity ,float *p_temperature)
  238. {

  239.         float rh=*p_humidity;             // rh:      12位 湿度
  240.         float t=*p_temperature;           // t:       14位 温度
  241.         float rh_lin;                     // rh_lin: 湿度 linear值
  242.         float rh_true;                    // rh_true: 湿度 ture值
  243.         float t_C;                        // t_C   : 温度 ℃

  244.         t_C=t*0.01 - 40;                  //补偿温度
  245.         rh_lin=-0.0000028*rh*rh + 0.0405*rh - 4;     //相对湿度非线性补偿
  246.         rh_true=rh/33;   
  247.         if(rh_true>26)
  248.                 rh_true=rh/33+1;
  249.         if(rh_true>33)
  250.                 rh_true=rh/33+1.5;
  251.         if(rh_true>40)
  252.                 rh_true=rh/33+3;       
  253.         if(rh_true>50)
  254.                 rh_true=rh/33+3.7;       
  255.         if(rh_true>70)
  256.                 rh_true=rh/33+3;       
  257.         if(rh_true>90)
  258.                 rh_true=rh/33+1.6;       

  259.     //rh_true=(t_C-25)*(0.01+0.00008*rh)+rh_lin;   //相对湿度对于温度依赖性补偿        ,仿真的时候去掉补偿

  260.                
  261.         if(rh_true>100)rh_true=100;       //湿度最大修正
  262.         if(rh_true<0.1)rh_true=0.1;       //湿度最小修正

  263.         *p_temperature=t_C;               //返回温度结果
  264.         *p_humidity=rh_true;              //返回湿度结果


  265. }


  266. void Covert_HT()
  267. {
  268.         value humi_val,temp_val;                //定义两个共同体,一个用于湿度,一个用于温度
  269.         uchar checksum;                        //CRC         
  270.         uchar error=0;
  271.         error=0;                                           //初始化error=0,即没有错误
  272.         error+=SHTXX_measure((unsigned char*)&temp_val.i,&checksum,TEMP); //温度测量
  273.         error+=SHTXX_measure((unsigned char*)&humi_val.i,&checksum,HUMI); //湿度测量
  274.         if(error!=0) SHTXX_Init();                 ////如果发生错误,系统复位
  275.         else
  276.         {
  277.                 humi_val.f=(float)humi_val.i;                   //转换为浮点数
  278.                 temp_val.f=(float)temp_val.i;                   //转换为浮点数
  279.                 SHTXX_calc(&humi_val.f,&temp_val.f);            //修正相对湿度及温度
  280.                
  281.                 real_tempure =temp_val.f+1;           //修正一下偏
  282.                 real_humi    = humi_val.f-1;

  283.                 if(real_tempure>=0)
  284.                 {
  285.                   TEMP_BUF[0]=real_tempure/100+'0';                     //温度百位
  286.                
  287.                 if (TEMP_BUF[0]==0x30) TEMP_BUF[0]=0x20;
  288. ……………………

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

所有资料51hei提供下载:
DHT11说明书081206.7z (661.22 KB, 下载次数: 33)
SHT11.7z (1.68 MB, 下载次数: 48)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

7#
ID:748788 发表于 2020-9-9 21:38 | 只看该作者
sht11的程序应该不适用于dht11
回复

使用道具 举报

6#
ID:765415 发表于 2020-9-4 16:36 | 只看该作者
这个是SHT的,不是DHT的,两个元器件不一样,SHT是50多块钱一个
回复

使用道具 举报

5#
ID:743443 发表于 2020-8-2 18:16 | 只看该作者
这是dht11吗?
咋跟标题不一样呀
回复

使用道具 举报

地板
ID:639106 发表于 2020-7-20 10:24 | 只看该作者
百度网盘链接:https://pan.baidu.com/s/1B5kp8cX2hZjL2ays8MwBOw
提取码:1234
回复

使用道具 举报

板凳
ID:136485 发表于 2020-7-20 08:52 | 只看该作者
谢谢分享,刚好手头上有一个这个片子,那天有空玩一下
回复

使用道具 举报

沙发
ID:639106 发表于 2020-7-19 17:07 | 只看该作者
这论坛附件有些不好使
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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