一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 1393|回复: 5
收起左侧

单片机+DHT11温湿度+1602液晶显示

[复制链接]
发表于 2020-7-23 20:17 | 显示全部楼层 |阅读模式
这资料蛮好的,拿出来分享......undefined仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
  1. 01.#include <reg52.h>

  2. 02.#include <intrins.h>

  3. 03.

  4. 04.#define uchar unsigned char         //宏定义方便以后用

  5. 05.#define uint unsigned int  

  6. 06.#define ulong unsigned long

  7. 07.

  8. 08.//SHT11接口

  9. 09.sbit DATA = P2^5;

  10. 10.sbit SCK = P2^4;

  11. 11.

  12. 12.typedef union                   //定义共同类型

  13. 13.{

  14. 14.  unsigned int i;           //i表示测量得到的温湿度数据(int 形式保存的数据)

  15. 15.  float f;                           //f表示测量得到的温湿度数据(float 形式保存的数据)

  16. 16.} value;

  17. 17.

  18. 18.enum {TEMP,HUMI};

  19. 19.

  20. 20.uchar TEMP_BUF[7];                                         //用于记录温度

  21. 21.uchar HUMI_BUF[5];                                         //用于记录湿度

  22. 22.

  23. 23.int real_tempure=0;                //实际温度

  24. 24.uchar real_humi=0;

  25. 25.

  26. 26.

  27. 27.//LCD port

  28. 28.sbit LcdRs= P2^0;

  29. 29.sbit LcdRw= P2^1;

  30. 30.sbit LcdEn= P2^2;

  31. 31.sfr  DBPort= 0x80;                //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

  32. 32.

  33. 33.

  34. 34.//向LCD写入命令或数据************************************************************

  35. 35.#define LCD_COMMAND                        0      // Command

  36. 36.#define LCD_DATA                        1      // Data

  37. 37.#define LCD_CLEAR_SCREEN        0x01      // 清屏

  38. 38.#define LCD_HOMING                  0x02      // 光标返回原点

  39. 39.

  40. 40.

  41. 41.//设置显示模式************************************************************

  42. 42.#define LCD_SHOW                        0x04    //显示开

  43. 43.#define LCD_HIDE                        0x00    //显示关         

  44. 44.

  45. 45.#define LCD_CURSOR                        0x02         //显示光标

  46. 46.#define LCD_NO_CURSOR                0x00    //无光标                     

  47. 47.

  48. 48.#define LCD_FLASH                        0x01    //光标闪动

  49. 49.#define LCD_NO_FLASH                0x00    //光标不闪动

  50. 50.//内部等待函数**************************************************************************

  51. 51.unsigned char LCD_Wait(void)

  52. 52.{

  53. 53.        LcdRs=0;

  54. 54.        LcdRw=1;        _nop_();

  55. 55.        LcdEn=1;        _nop_();

  56. 56.        _nop_();

  57. 57.        _nop_();

  58. 58.        _nop_();

  59. 59.        LcdEn=0;

  60. 60.        return DBPort;               

  61. 61.}

  62. 62.

  63. 63.void LCD_Write(bit style, unsigned char input)

  64. 64.{

  65. 65.        LcdEn=0;

  66. 66.        LcdRs=style;

  67. 67.        LcdRw=0;                _nop_();

  68. 68.        DBPort=input;        _nop_();//注意顺序

  69. 69.        LcdEn=1;                _nop_();//注意顺序

  70. 70.        LcdEn=0;                _nop_();

  71. 71.        LCD_Wait();        

  72. 72.}

  73. 73.

  74. 74.void LCD_SetDisplay(unsigned char DisplayMode)

  75. 75.{

  76. 76.        LCD_Write(LCD_COMMAND, 0x08|DisplayMode);        

  77. 77.}

  78. 78.

  79. 79.//设置输入模式************************************************************

  80. 80.#define LCD_AC_UP                        0x02

  81. 81.#define LCD_AC_DOWN                        0x00      // default

  82. 82.

  83. 83.#define LCD_MOVE                        0x01      // 画面可平移

  84. 84.#define LCD_NO_MOVE                        0x00      //default

  85. 85.

  86. 86.void LCD_SetInput(unsigned char InputMode)

  87. 87.{

  88. 88.        LCD_Write(LCD_COMMAND, 0x04|InputMode);

  89. 89.}

  90. 90.

  91. 91.

  92. 92.//初始化LCD************************************************************

  93. 93.void LCD_Initial()

  94. 94.{

  95. 95.        LcdEn=0;

  96. 96.        LCD_Write(LCD_COMMAND,0x38);           //8位数据端口,2行显示,5*7点阵

  97. 97.        LCD_Write(LCD_COMMAND,0x38);

  98. 98.        LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);    //开启显示, 无光标

  99. 99.        LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);   //清屏

  100. 100.        LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);       //AC递增, 画面不动

  101. 101.}

  102. 102.

  103. 103.//************************************************************************

  104. 104.void GotoXY(unsigned char x, unsigned char y)

  105. 105.{

  106. 106.        if(y==0)

  107. 107.                LCD_Write(LCD_COMMAND,0x80|x);

  108. 108.        if(y==1)

  109. 109.                LCD_Write(LCD_COMMAND,0x80|(x-0x40));

  110. 110.}

  111. 111.

  112. 112.void Print(unsigned char *str)         //在LCD上显示数据,内部调用

  113. 113.{

  114. 114.        while(*str!='\0')

  115. 115.        {

  116. 116.                LCD_Write(LCD_DATA,*str);

  117. 117.                str++;

  118. 118.        }

  119. 119.}

  120. 120.

  121. 121.void LCD_Print(unsigned char x, unsigned char y, unsigned char *str) //指定的位置打印指定数据

  122. 122.{

  123. 123.  GotoXY(x,y);

  124. 124.  Print(str);

  125. 125.}

  126. 126.

  127. 127./********************************************************************

  128. 128.* 名称 : Delay_1ms()

  129. 129.* 功能 : 延时子程序

  130. 130.* 输入 : x

  131. 131.* 输出 : 无

  132. 132.***********************************************************************/

  133. 133.void Delay(uint i)//延时

  134. 134.{

  135. 135.        uint x,j;

  136. 136.        for(j=0;j<i;j++)

  137. 137.        for(x=0;x<=148;x++);        

  138. 138.}

  139. 139.

  140. 140.

  141. 141./***********************************************************************************************************************************************************/

  142. 142.

  143. 143.//SHT11程序

  144. 144.

  145. 145.

  146. 146.#define noACK 0                                //继续传输数据,用于判断是否结束通讯

  147. 147.#define ACK   1             //结束数据传输;

  148. 148.                                                        //地址  命令  读/写

  149. 149.#define STATUS_REG_W 0x06   //000   0011    0

  150. 150.#define STATUS_REG_R 0x07   //000   0011    1

  151. 151.#define MEASURE_TEMP 0x03   //000   0001    1

  152. 152.#define MEASURE_HUMI 0x05   //000   0010    1

  153. 153.#define RESET        0x1e   //000   1111    0

  154. 154.

  155. 155.

  156. 156.//写字节程序

  157. 157.char SHTXX_write_byte(unsigned char value)   

  158. 158.{

  159. 159.        unsigned char i,error=0;

  160. 160.        for (i=0x80;i>0;i/=2)             //shift bit for masking 高位为1,循环右移

  161. 161.        {

  162. 162.                if (i&value) DATA=1;          //和要发送的数相与,结果为发送的位

  163. 163.            else DATA=0;                        

  164. 164.            SCK=1;                          

  165. 165.            _nop_();_nop_();_nop_();        //延时3us

  166. 166.            SCK=0;

  167. 167.        }

  168. 168.        DATA=1;                           //释放数据线

  169. 169.        SCK=1;                           

  170. 170.        error=DATA;                       //检查应答信号,确认通讯正常

  171. 171.        _nop_();_nop_();_nop_();

  172. 172.        SCK=0;        

  173. 173.        DATA=1;

  174. 174.        return error;                     //error=1 通讯错误

  175. 175.}

  176. 176.

  177. 177.//读字节程序

  178. 178.char SHTXX_read_byte(unsigned char ack)

  179. 179.//----------------------------------------------------------------------------------

  180. 180.{

  181. 181.        unsigned char i,val=0;

  182. 182.        DATA=1;                           //释放数据线

  183. 183.        for(i=0x80;i>0;i>>=1)             //高位为1,循环右移

  184. 184.        {

  185. 185.                SCK=1;                        

  186. 186.            if(DATA) val=(val|i);        //读一位数据线的值

  187. 187.            SCK=0;      

  188. 188.        }

  189. 189.        DATA=!ack;                        //如果是校验,读取完后结束通讯;

  190. 190.        SCK=1;                           

  191. 191.        _nop_();_nop_();_nop_();          //延时3us

  192. 192.        SCK=0;   

  193. 193.        _nop_();_nop_();_nop_();      

  194. 194.        DATA=1;                           //释放数据线

  195. 195.        return val;

  196. 196.}

  197. 197.

  198. 198.//启动传输

  199. 199.void SHTXX_transstart(void)

  200. 200.// generates a transmission start

  201. 201.//       _____         ________

  202. 202.// DATA:      |_______|

  203. 203.//           ___     ___

  204. 204.// SCK : ___|   |___|   |______

  205. 205.{

  206. 206.           DATA=1; SCK=0;                   //准备

  207. 207.           _nop_();

  208. 208.          SCK=1;

  209. 209.           _nop_();

  210. 210.           DATA=0;

  211. 211.           _nop_();

  212. 212.          SCK=0;

  213. 213.           _nop_();_nop_();_nop_();

  214. 214.           SCK=1;

  215. 215.           _nop_();

  216. 216.          DATA=1;     

  217. 217.          _nop_();

  218. 218.           SCK=0;     

  219. 219.}

  220. 220.

  221. 221.

  222. 222.//连接复位

  223. 223.void SHTXX_Init(void)

  224. 224.// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart

  225. 225.//       _____________________________________________________         ________

  226. 226.// DATA:                                                      |_______|

  227. 227.//          _    _    _    _    _    _    _    _    _        ___     ___

  228. 228.// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______|   |___|   |______

  229. 229.{

  230. 230.        unsigned char i;

  231. 231.        DATA=1; SCK=0;                    //准备

  232. 232.        for(i=0;i<9;i++)                  //DATA保持高,SCK时钟触发9次,发送启动传输,通迅即复位

  233. 233.        {

  234. 234.                SCK=1;

  235. 235.            SCK=0;

  236. 236.        }

  237. 237.        SHTXX_transstart();                   //启动传输

  238. 238.}

  239. 239.

  240. 240. /*

  241. 241.//软复位程序

  242. 242.char SHTXX_softreset(void)

  243. 243.// resets the sensor by a softreset

  244. 244.{

  245. 245.        unsigned char error=0;

  246. 246.        SHTXX_Init();              //启动连接复位

  247. 247.        error+=SHTXX_write_byte(RESET);       //发送复位命令

  248. 248.        return error;                     //error=1 通讯错误

  249. 249.}

  250. 250.  */

  251. 251.

  252. 252.

  253. 253.           

  254. 254.//温湿度测量

  255. 255.char SHTXX_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)

  256. 256.// 进行温度或者湿度转换,由参数mode决定转换内容;

  257. 257.{

  258. 258.//        enum {TEMP,HUMI};                 //已经在头文件中定义

  259. 259.        unsigned error=0;

  260. 260.        unsigned int i;

  261. 261.

  262. 262.        SHTXX_transstart();                   //启动传输

  263. 263.        switch(mode)                     //选择发送命令

  264. 264.    {        

  265. 265.                case TEMP : error+=SHTXX_write_byte(MEASURE_TEMP); break;                   //测量温度

  266. 266.            case HUMI : error+=SHTXX_write_byte(MEASURE_HUMI); break;                   //测量湿度

  267. 267.            default     : break;

  268. 268.        }

  269. 269.        for (i=0;i<65535;i++) if(DATA==0) break; //等待测量结束

  270. 270.        if(DATA) error+=1;                // 如果长时间数据线没有拉低,说明测量错误

  271. 271.        *(p_value) =SHTXX_read_byte(ACK);    //读第一个字节,高字节 (MSB)

  272. 272.        *(p_value+1)=SHTXX_read_byte(ACK);    //读第二个字节,低字节 (LSB)

  273. 273.        *p_checksum =SHTXX_read_byte(noACK); //read CRC校验码

  274. 274.        return error;                                         // error=1 通讯错误

  275. 275.}

  276. 276.

  277. 277.//温湿度值标度变换及温度补偿

  278. 278.void SHTXX_calc(float *p_humidity ,float *p_temperature)

  279. 279.{

  280. 280.

  281. 281.        float rh=*p_humidity;             // rh:      12位 湿度

  282. 282.        float t=*p_temperature;           // t:       14位 温度

  283. 283.        float rh_lin;                     // rh_lin: 湿度 linear值

  284. 284.        float rh_true;                    // rh_true: 湿度 ture值

  285. 285.        float t_C;                        // t_C   : 温度 ℃

  286. 286.

  287. 287.        t_C=t*0.01 - 40;                  //补偿温度

  288. 288.        rh_lin=-0.0000028*rh*rh + 0.0405*rh - 4;     //相对湿度非线性补偿

  289. 289.        rh_true=rh/33;   

  290. 290.        if(rh_true>26)

  291. 291.                rh_true=rh/33+1;

  292. 292.        if(rh_true>33)

  293. 293.                rh_true=rh/33+1.5;

  294. 294.        if(rh_true>40)

  295. 295.                rh_true=rh/33+3;        

  296. 296.        if(rh_true>50)

  297. 297.                rh_true=rh/33+3.7;        

  298. 298.        if(rh_true>70)

  299. 299.                rh_true=rh/33+3;        

  300. 300.        if(rh_true>90)

  301. 301.                rh_true=rh/33+1.6;        

  302. 302.

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

  304. 304.

  305. 305.               

  306. 306.        if(rh_true>100)rh_true=100;       //湿度最大修正

  307. 307.        if(rh_true<0.1)rh_true=0.1;       //湿度最小修正

  308. 308.

  309. 309.        *p_temperature=t_C;               //返回温度结果

  310. 310.        *p_humidity=rh_true;              //返回湿度结果

  311. 311.

  312. 312.

  313. 313.}

  314. 314.

  315. 315.

  316. 316.void Covert_HT()

  317. 317.{

  318. 318.        value humi_val,temp_val;                //定义两个共同体,一个用于湿度,一个用于温度

  319. 319.        uchar checksum;                        //CRC         

  320. 320.        uchar error=0;

  321. 321.        error=0;                                           //初始化error=0,即没有错误

  322. 322.        error+=SHTXX_measure((unsigned char*)&temp_val.i,&checksum,TEMP); //温度测量

  323. 323.        error+=SHTXX_measure((unsigned char*)&humi_val.i,&checksum,HUMI); //湿度测量

  324. 324.        if(error!=0) SHTXX_Init();                 ////如果发生错误,系统复位

  325. 325.        else

  326. 326.        {

  327. 327.                humi_val.f=(float)humi_val.i;                   //转换为浮点数

  328. 328.                 temp_val.f=(float)temp_val.i;                   //转换为浮点数

  329. 329.                 SHTXX_calc(&humi_val.f,&temp_val.f);            //修正相对湿度及温度

  330. 330.               

  331. 331.                real_tempure =temp_val.f+1;           //修正一下偏

  332. 332.                real_humi    = humi_val.f-1;

  333. 333.

  334. 334.                if(real_tempure>=0)

  335. 335.                {

  336. 336.                  TEMP_BUF[0]=real_tempure/100+'0';                     //温度百位

  337. 337.               

  338. 338.                if (TEMP_BUF[0]==0x30) TEMP_BUF[0]=0x20;

  339. 339.……………………

  340. 340.

  341. 341.…………限于本文篇幅 余下代码请下载附件…………
复制代码
SHT11.zip (1.92 MB, 下载次数: 11) DHT11说明书081206.zip (662.32 KB, 下载次数: 10)
 楼主| 发表于 2020-7-23 20:20 | 显示全部楼层
截图202007232020036239..png
发表于 2020-7-24 09:16 | 显示全部楼层
学习学习,谢谢楼主分享。
发表于 2020-7-24 14:11 | 显示全部楼层
感谢楼主分享,继续。。。
发表于 2020-9-7 17:41 | 显示全部楼层
谢谢分享!!!
发表于 2020-9-17 07:16 | 显示全部楼层
谢谢楼主分享。学习一下!!!

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-5-7 20:43 , Processed in 0.070764 second(s), 46 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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