找回密码
 立即注册

QQ登录

只需一步,快速开始

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

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

  [复制链接]
跳转到指定楼层
楼主


DHT11驱动程序参考
http://www.51hei.com/bbs/dpj-112282-1.html
http://www.51hei.com/bbs/dpj-38067-1.html

1602驱动程序参考
http://www.51hei.com/bbs/dpj-24671-1.html
  1. /*********************************************************************************************
  2. 程序名:    DHT11-1602
  3. 编写人:    fby
  4. 编写时间:  2019年3月21日
  5. 硬件支持:  STC89C52RC  DHT11  LCD1602
  6. 接口说明:  DHT11:VCC DATA NC GND
  7. *********************************************************************************************
  8. 说明:1、单片机是STC89C52RC,晶振频率11.0592MHz,实验成功。
  9.           2、好东西要共享,大家随意折腾~~
  10. *********************************************************************************************/
  11. #include<reg51.h>
  12. #include<intrins.h>

  13. #define uchar unsigned char        //无符号字符型类型数据
  14. #define uint unsigned int //无符号整型数据
  15. #define IODATA  P0

  16. uchar dat_r[4];          //用于存放从DHT11读取到的数值

  17. sbit DATA=P2^2;   //定义数据线
  18. sbit RS=P1^0; //定义rs端口
  19. sbit RW=P1^1; //定义rw端口
  20. sbit E=P2^5; //定义en端口


  21. /*********************************************************************************************
  22. 函数名:延时函数
  23. 调  用:Delay30us();/Delay20ms();/Delay1s();
  24. 参  数:无
  25. 返回值:无
  26. 结  果:延时相应时间
  27. 备  注:振荡晶体为11.0592MHz(所有延时函数Copy自STC-ISP(v6.85).exe)
  28. **********************************************************************************************/
  29. void Delay30us()                //@11.0592MHz-40
  30. {
  31.         unsigned char i;

  32.         i = 11;
  33.         while (--i);
  34. }


  35. void Delay20ms()                //@11.0592MHz
  36. {
  37.         unsigned char i, j;

  38.         i = 36;
  39.         j = 217;
  40.         do
  41.         {
  42.                 while (--j);
  43.         } while (--i);
  44. }


  45. void Delay1s()                //@11.0592MHz
  46. {
  47.         unsigned char i, j, k;

  48.         _nop_();
  49.         i = 8;
  50.         j = 1;
  51.         k = 243;
  52.         do
  53.         {
  54.                 do
  55.                 {
  56.                         while (--k);
  57.                 } while (--j);
  58.         } while (--i);
  59. }


  60. /*********************************************************************************************
  61. 函数名:DHT11启动函数
  62. 调  用:无
  63. 参  数:无
  64. 返回值:无
  65. 结  果:DHT11开始工作
  66. 备  注:
  67. **********************************************************************************************/
  68. void DHT11_start()                 // 主机控制DHT11开始工作
  69. {
  70.    DATA=1;                                 // 主线空闲状态
  71.    _nop_();
  72.    _nop_();
  73.    DATA=0;                                 // 主机发送开始工作信号
  74.    Delay20ms();   //延时18ms以上
  75.    DATA=1;                                 // 拉高并延时等待DHT11响应
  76.    Delay30us();
  77. }
  78. /*********************************************************************************************
  79. 函数名:DHT11读数据函数
  80. 调  用:? = DHT11_rec_byte();
  81. 参  数:无
  82. 返回值:
  83. 结  果:读DHT11数据并保存到dat
  84. 备  注:
  85. **********************************************************************************************/

  86. uchar DHT11_rec_byte()      //接收一个字节
  87. {
  88.    uchar i,dat=0;
  89.   for(i=0;i<8;i++)    //从高到低依次接收8位数据
  90.    {         
  91.       while(!DATA);   ////等待50us低电平过去
  92.       Delay30us();
  93.           Delay30us();     //延时60us,如果还为高则数据为1,否则为0
  94.       dat<<=1;           //左移位使正确接收8位数据,数据为0时直接移位
  95.       if(DATA==1)    //数据为1时,使dat加1来接收数据1
  96.          dat+=1;
  97.       while(DATA);  //等待数据线拉低   
  98.     }  
  99.     return dat;
  100. }

  101. /*********************************************************************************************
  102. 函数名:接收DHT11的40位的数据并校验
  103. 调  用:? = DHT11_receive();
  104. 参  数:无
  105. 返回值:无
  106. 结  果:结果保存到dat_r[i]中
  107. 备  注:
  108. **********************************************************************************************/
  109. void DHT11_receive()      //接收40位的数据
  110. {
  111.     uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
  112.     DHT11_start();                 // 主机控制DHT11开始工作
  113.     if(DATA==0)
  114.     {
  115.         while(DATA==0);   //等待拉高     
  116.         Delay30us();
  117.                 Delay30us();
  118.                 Delay30us();  //拉高后延时80us
  119.         R_H=DHT11_rec_byte();    //接收湿度高八位  
  120.         R_L=DHT11_rec_byte();    //接收湿度低八位  
  121.         T_H=DHT11_rec_byte();    //接收温度高八位  
  122.         T_L=DHT11_rec_byte();    //接收温度低八位
  123.         revise=DHT11_rec_byte(); //接收校正位

  124.         Delay30us();    //结束

  125.         if((R_H+R_L+T_H+T_L)==revise)      //校正
  126.         {
  127.             RH=R_H;
  128.             RL=R_L;
  129.             TH=T_H;
  130.             TL=T_L;
  131.         }
  132.         /*数据处理,方便显示*/
  133.         dat_r[0]='0'+(RH/10);
  134.         dat_r[1]='0'+(RH%10);
  135.         dat_r[2]='0'+(TH/10);
  136.         dat_r[3]='0'+(TH%10);
  137.     }
  138. }

  139. /********************************************************************
  140. * 名称 : bit Busy(void)
  141. * 功能 : 这个是一个读状态函数,读出函数是否处在忙状态
  142. * 输入 : 输入的命令值
  143. * 输出 : 无
  144. ***********************************************************************/
  145. void Busy(void)
  146. {
  147. bit busy_flag = 1;
  148. IODATA  = 0xff;
  149. RS = 0;          //指令关
  150. Delay30us();
  151. RW = 1;          //读状态
  152. Delay30us();
  153. E = 1;        //使能高电平
  154. while(1)
  155. {
  156. busy_flag = (bit)(IODATA  & 0x80); //强制取最高位
  157. if(busy_flag == 0)
  158. {
  159. break;
  160. }
  161. }
  162. E = 0;           //E 1->0,rs=0,rw=1,
  163.            //将数据寄存器内的数据读到DB0~DB7,分别将状态标志BF和地址计数器(AC)内容读到DB7和DB6~DB0。

  164. }

  165. /********************************************************************
  166. * 名称 : lcd1602_write_cmd(uchar del)
  167. * 功能 : 1602命令函数
  168. * 输入 : 输入的命令值
  169. * 输出 : 无
  170. ***********************************************************************/
  171. void lcd1602_write_cmd(uchar del)
  172. {
  173. RS = 0;
  174. Delay30us();
  175. RW = 0;
  176. Delay30us();
  177. E = 0;
  178. Delay30us();
  179. IODATA  = del;
  180. Delay30us();
  181. E = 1;
  182. Delay30us();
  183. E = 0;                        //E 1->0,rs=0,rw=0, 将指令代码写入指令寄存器中
  184. }

  185. /********************************************************************
  186. * 名称 : lcd1602_write_data(uchar del)
  187. * 功能 : 1602写数据函数
  188. * 输入 : 需要写入1602的数据
  189. * 输出 : 无
  190. ***********************************************************************/

  191. void lcd1602_write_data(uchar del)
  192. {
  193. Busy();      
  194. Delay30us();
  195. RS = 1;
  196. Delay30us();
  197. RW = 0;
  198. Delay30us();
  199. E = 0;
  200. Delay30us();
  201. IODATA  = del;
  202. Delay30us();
  203. E = 1;
  204. Delay30us();
  205. E = 0;                          //E 1->0,rs=1,rw=0, 数据写入数据寄存器中
  206. }

  207. /********************************************************************
  208. * 名称 : lcd1602_init()
  209. * 功能 : 1602初始化,请参考1602的资料
  210. * 输入 : 无
  211. * 输出 : 无
  212. ***********************************************************************/
  213. void lcd1602_init(void)
  214. {
  215. Delay20ms();
  216. lcd1602_write_cmd(0x38);         //8位数据,双列,5*7字形
  217. Delay20ms();
  218. lcd1602_write_cmd(0x38);
  219. Delay20ms();
  220. lcd1602_write_cmd(0x38);
  221. Busy();
  222. lcd1602_write_cmd(0x08);// 只开显示
  223. Busy();   
  224. lcd1602_write_cmd(0x01);        //清屏
  225. Busy();
  226. lcd1602_write_cmd(0x06);//显示地址递增,即写一个数据后,显示位置右移一位
  227. Busy();
  228. lcd1602_write_cmd(0x0c);        //开启显示屏,关光标,光标不闪烁
  229. }

  230. /********************************************************************
  231. * 名称 : lcd1602_char(uchar hang,uchar lie,char sign)
  232. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
  233. L1602_char(1,5,'b')
  234. * 输入 : 行,列,需要输入1602的数据
  235. * 输出 : 无
  236. ***********************************************************************/
  237. void lcd1602_char(uchar hang,uchar lie,char sign)
  238. {
  239. uchar a;
  240. if(hang == 1)
  241. {
  242. a = 0x80;
  243. }
  244. if(hang == 2)
  245. {
  246. a = 0xc0;
  247. }
  248. a = a + lie - 1;
  249. Busy();
  250. lcd1602_write_cmd(a);  //置数据存贮器地址
  251. Busy();
  252. lcd1602_write_data(sign);
  253. }

  254. /********************************************************************
  255. * 名称 : lcd1602_string(uchar hang,uchar lie,uchar *p)
  256. * 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
  257. L1602_string(1,5,"ab cd ef;")
  258. * 输入 : 行,列,需要输入1602的数据
  259. * 输出 : 无
  260. ***********************************************************************/
  261. void lcd1602_string(uchar hang,uchar lie,uchar *p)
  262. {
  263. uchar a;
  264. if(hang == 1)
  265. {
  266. a = 0x80;
  267. }
  268. if(hang == 2)
  269. {
  270. a = 0xc0;
  271. }
  272. a = a + lie - 1;
  273. while(1)
  274. {
  275. Busy();
  276. lcd1602_write_cmd(a);
  277. Busy();
  278. lcd1602_write_data(*p);
  279. a++;
  280. p++;   
  281. if((*p == '\0')||(a==0x90)||(a==0xd0)) //字符结束或每行最后一个字符
  282. {
  283. break;
  284. }
  285. }
  286. }

  287. /*********************************************************************************************
  288. 函数名:主函数
  289. 调  用:无
  290. 参  数:无
  291. 返回值:无
  292. 结  果:读DHT11数据并送到1602显示
  293. 备  注:
  294. **********************************************************************************************/
  295. void main (void)
  296. {
  297.         
  298.         Delay20ms();
  299.         lcd1602_init();                //LCD初始化
  300.         while(1)
  301.         {
  302.                 Delay1s();                //经测试,两次连读要至少延时80ms        
  303.                 DHT11_receive();//接受数据
  304.                 lcd1602_string(1,1,"SHIDU:");
  305.                 lcd1602_string(2,1,"WENDU:");
  306.                 lcd1602_char(1,7,dat_r[0]);
  307.                 lcd1602_char(1,8,dat_r[1]);
  308.                 lcd1602_char(2,7,dat_r[2]);
  309.                 lcd1602_char(2,8,dat_r[3]);
  310.                 lcd1602_string(1,9,"%");
  311.                 lcd1602_char(2,9,0XDF);
  312.                 lcd1602_string(2,10,"C");
  313.                
  314.         }
  315. }
复制代码

全部资料51hei下载地址:
DHT11-1602.rar (40.01 KB, 下载次数: 579)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:404454 发表于 2019-3-24 08:27 | 只看该作者
支持,但显示太复杂了,符号数字一目了然。
回复

使用道具 举报

板凳
ID:483579 发表于 2019-4-7 13:23 来自手机 | 只看该作者
hu2018y 发表于 2019-3-24 08:27
支持,但显示太复杂了,符号数字一目了然。

可以再普中的板子上实验嘛?
回复

使用道具 举报

地板
ID:503160 发表于 2019-4-11 09:27 | 只看该作者
请问有PROTEUS仿真图吗
回复

使用道具 举报

5#
ID:509459 发表于 2019-4-11 10:58 | 只看该作者
学习学习                                             
回复

使用道具 举报

6#
ID:403562 发表于 2019-4-11 17:26 | 只看该作者
宁小小 发表于 2019-4-7 13:23
可以再普中的板子上实验嘛?

不行,我试了
回复

使用道具 举报

7#
ID:514728 发表于 2019-4-24 13:14 | 只看该作者
不错啊
学习了
回复

使用道具 举报

8#
ID:501681 发表于 2019-4-29 13:37 | 只看该作者
宁小小 发表于 2019-4-7 13:23
可以再普中的板子上实验嘛?

我试了好像不显示
回复

使用道具 举报

9#
ID:576600 发表于 2019-7-25 20:26 | 只看该作者
非常感谢,下载一次点亮,温湿度显示正常。
回复

使用道具 举报

10#
ID:576600 发表于 2019-7-25 20:26 | 只看该作者
宁小小 发表于 2019-4-7 13:23
可以再普中的板子上实验嘛?

可以的,我试了,显示正常。
回复

使用道具 举报

11#
ID:589811 发表于 2019-7-28 11:22 | 只看该作者
宁小小 发表于 2019-4-7 13:23
可以再普中的板子上实验嘛?

可以的,重新定义一下引脚就可以
回复

使用道具 举报

12#
ID:599167 发表于 2019-8-11 17:36 | 只看该作者
正好找这个,居然还真的有
回复

使用道具 举报

13#
ID:664479 发表于 2019-12-15 18:03 | 只看该作者
为什么我的液晶显示屏(就复制了这个程序)显示不了啊   用的温湿度模块儿也都是一样的  但是就是没有数据
回复

使用道具 举报

14#
ID:654535 发表于 2019-12-19 11:05 | 只看该作者
我在protus实现你的程序为什么实现不了啊,lm0161黑频
回复

使用道具 举报

15#
ID:341833 发表于 2020-1-19 23:54 | 只看该作者
显示不了呀
回复

使用道具 举报

16#
ID:687485 发表于 2020-1-20 08:49 | 只看该作者
想下载学习一下。
回复

使用道具 举报

17#
ID:745988 发表于 2020-5-7 20:04 | 只看该作者
老哥,我用你的程序,咋1062屏上还是啥都不显示。
回复

使用道具 举报

18#
ID:745988 发表于 2020-5-7 20:14 | 只看该作者
我的那个数值咋显示不清楚呢
回复

使用道具 举报

19#
ID:757900 发表于 2020-6-15 20:40 来自手机 | 只看该作者
不错谢谢分享 有你更精彩
回复

使用道具 举报

20#
ID:780711 发表于 2020-6-16 14:19 | 只看该作者
请问为什么在proteus上面仿真没有显示
回复

使用道具 举报

21#
ID:803001 发表于 2020-8-4 10:29 | 只看该作者
lqqqqqqqq 发表于 2020-6-16 14:19
请问为什么在proteus上面仿真没有显示

我也是
回复

使用道具 举报

22#
ID:981034 发表于 2021-11-16 08:23 | 只看该作者
谢谢,有注释
回复

使用道具 举报

23#
ID:1047453 发表于 2022-10-12 17:43 | 只看该作者

把那个data rs rw 还有e的引脚改一下就可以了
回复

使用道具 举报

24#
ID:1013894 发表于 2022-12-5 20:08 | 只看该作者
前排过来学习一下
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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