找回密码
 立即注册

QQ登录

只需一步,快速开始

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

带详细注释的DHT11温湿度传感器单片机程序 lcd1602显示

[复制链接]
跳转到指定楼层
楼主
ID:562317 发表于 2019-6-14 09:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. typedef unsigned char BYTE;
  4. typedef unsigned int WORD;
  5. #define uint unsigned int
  6. #define uchar unsigned char
  7. sbit io=P1^0; //dht11data 端接单片机的 P1^0 口//
  8. sbit rw=P0^6; //一下三行是设置 lcd1602 的使能端 //
  9. sbit rs=P0^7;
  10. sbit ep=P0^5;
  11. typedef bit BOOL; //此声明一个布尔型变量即真或假 //
  12. uchar data_byte;
  13. uchar RH,RL,TH,TL;
  14. //*************** 延时函数 *************************************
  15. void delay(uchar ms) // 延时模块 //
  16. {
  17.      uchar i;
  18.      while(ms--)  
  19.      for(i=0;i<100;i++);
  20. }
  21. void delay1()           //一个for循环大概需要8个多机器周期一个机器周期为1us
  22. {                       //晶振为 12MHz 也就是说本函数延时8us多
  23.    uchar i;                         // 此延时函数必须德稍微精确一点
  24.    for(i=0;i<1;i++);
  25. }


  26. //***************************************************************
  27. //lcd 模块 //
  28. BOOL lcd_bz()// 测试 lcd 忙碌状态 返回值为布尔型数值 真或假 '1'.'0'
  29. {
  30.         BOOL result;
  31.         rs=0; // 读忙信号
  32.         rw=1;
  33.         ep=1;
  34.         _nop_();
  35.         _nop_();
  36.         _nop_();
  37.         _nop_();
  38.         result = (BOOL)(P2&0x80);
  39.         ep=0;
  40.         return result;
  41. }
  42. void write_cmd(uchar cmd)// 写指令 //
  43. {
  44.         while (lcd_bz());
  45.         rs=0;
  46.         rw=0;
  47.         ep=0;
  48.         _nop_();
  49.         _nop_();
  50.         P2=cmd ;
  51.         _nop_();
  52.         _nop_();
  53.         _nop_();
  54.         _nop_();
  55.         ep=1;
  56.         _nop_();
  57.         _nop_();
  58.         _nop_();
  59.         _nop_();
  60.         ep=0;
  61. }
  62. void write_addr(uchar addr)// 写地址 //
  63. {
  64.    write_cmd(addr|0x80);//LCD第一行的首地址为0x80第二行的首地址为0x80+0x40=0xc0
  65. }
  66. void write_byte(uchar dat) // 写字节 //
  67. {
  68.         while (lcd_bz());
  69.         rs=1;
  70.         rw=0;
  71.         ep=0;
  72.         _nop_();
  73.         _nop_();
  74.         P2=dat ;
  75.         _nop_();
  76.         _nop_();
  77.         _nop_();
  78.         _nop_();
  79.         ep=1;
  80.         _nop_();
  81.         _nop_();
  82.         _nop_();
  83.         _nop_();
  84.         ep=0;
  85. }
  86. void lcd_init() //lcd 初始化 //
  87. {
  88.         write_cmd(0x38);// 设置 LCD 两行显示 一个数据由 5*7 点阵表示 ,数据由 8 跟线传输
  89.         delay(1);
  90.         write_cmd(0x0c);// 清除屏幕显示
  91.         delay(1);
  92.         write_cmd(0x06);// 设定输入方式 增量不移位
  93.         delay(1);
  94.         write_cmd(0x01);// 开整体显示 关光标 不闪烁
  95.         delay(1);
  96. }
  97. void display(uchar addr,uchar q)// 在某一地址上显示内容 adder 表示的是地址偏移量 q 表 示显示的字符或数字 //
  98. {
  99.         delay(10);
  100.         write_addr(addr);
  101.         write_byte(q);
  102.         delay(1);// 修改此时间 可以改变 LCD 上数值跳变的数度
  103. }
  104. //**************************dht11 测试某块 *************************************//
  105. void start()// 开始信号
  106. {
  107.         io=1;
  108.         delay1();
  109.         io=0;
  110.         delay(25);// 主机把总线拉低必须大于 18ms 保证 DHT11 能检测到起始信号
  111.         io=1; //发送开始信号结束后 拉高电平延时 20-40us
  112.         delay1();// 以下三个延时函数差不多为 24us 符合要求
  113.         delay1();
  114.         delay1();
  115. }
  116.         uchar receive_byte()//接收一个字节 //
  117. {
  118.         uchar i,temp;
  119.         for(i=0;i<8;i++)// 接收 8bit 的数据
  120. {
  121.         while(!io);// 等待 50us的低电平开始信号结束
  122.         delay1();//开始信号结束之后 延时 26us-28us 以下三个延时函数
  123.         delay1();
  124.         delay1();
  125.         temp=0;//时间为 26us-28us 表示接收的为数据 '0'
  126.         if(io==1)
  127.         temp=1; //如果 26us-28us之后 还为高电平 则表示接收的数据为 '1'
  128.         while(io);// 等待数据信号高电平 '0'为 26us-28us '1'为 70us
  129.         data_byte<<=1;// 接收的数据为高位在前 右移
  130.         data_byte|=temp;
  131. }
  132. return data_byte;
  133. }
  134. void receive()// 接收数据 //
  135. {
  136.         uchar T_H,T_L,R_H,R_L,check,num_check,i;
  137.         start();// 开始信号 //
  138.         io=1; //主机设为输入 判断从机 DHT11 响应信号
  139.         if(!io)// 判断从机是否有低电平响应信号 //
  140. {
  141. while(!io);// 判断从机发出 80us 的低电平响应信号是否结束 //
  142.         while(io);// 判断从机发出 80us 的高电平是否结束 如结束则主机进入数据接收状态
  143.         R_H=receive_byte();// 湿度高位
  144.         R_L=receive_byte();// 湿度低位
  145.         T_H=receive_byte();// 温度高位
  146.         T_L=receive_byte();// 温度低位
  147.         check=receive_byte();// 校验位
  148.         io=0; // 当最后一 bit 数据接完毕后 从机拉低电平 50us//
  149.     for(i=0;i<7;i++)// 差不多 50us 的延时
  150.         delay1();
  151.         io=1;// 总线由上拉电阻拉高 进入空闲状态
  152.         num_check=R_H+R_L+T_H+T_L;
  153.         if(num_check==check)// 判断读到的四个数据之和是否与校验位相同
  154. {
  155.         RH=R_H;
  156.         RL=R_L;
  157.         TH=T_H;
  158.         TL=T_L;
  159.         check=num_check;
  160. }
  161. }
  162. }
  163. //*****************************************************************************
  164. void main()// 主函数模块 //
  165. {
  166.         lcd_init();// 初始化 LCD
  167.         while(1)
  168.   {
  169.         receive();// 接收数据
  170.         display(0x00,'R');//LCD 的第一行显示
  171.         display(0x01,':');
  172.         display(0x02,RH/10+0x30); //0x30 表示 带字库的 LCD1602 中 0x30 的位置放有数字 0 RH/10+0x30 即表示湿度的十位数字在字库 RH/10+0x30 的位置处放着
  173.         display(0x03,RH%10+0x30);
  174.         display(0X04,'%');
  175.         display(0x40,'T');//LCD 的第二行显示
  176.         display(0x41,':');
  177.         display(0x42,TH/10+0x30);
  178.         display(0x43,TH%10+0x30);
  179.         display(0x44,0xdf);// 以下两个是温度单位的处理
  180.         display(0x45,0x43);
  181.   }
  182. }
复制代码

所有资料51hei提供下载:
温湿度传感器.rar (23.79 KB, 下载次数: 98)


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

使用道具 举报

沙发
ID:432200 发表于 2019-6-15 12:21 | 只看该作者
烧入单片机后LCD全是黑块,是什么原因
回复

使用道具 举报

板凳
ID:284488 发表于 2019-6-27 12:35 | 只看该作者
可能是Delay时间函数的问题,需调整看看。
回复

使用道具 举报

地板
ID:284488 发表于 2019-6-27 15:07 | 只看该作者
试过确认是LCD1602的副程序需修正,修正后就正常显示了。
回复

使用道具 举报

5#
ID:573698 发表于 2019-6-27 21:00 | 只看该作者
副程序怎么修正呢?
回复

使用道具 举报

6#
ID:284488 发表于 2019-6-28 22:49 | 只看该作者
因每个人用的板子可能都不太相同,程序上一些接口就要修改,不能完全照单直接烧入单片机中,用的晶振不同时间可能也要微调,若你有需要我改后的程序参考我再发给你好了,相互学习有助成长。
回复

使用道具 举报

7#
ID:738997 发表于 2020-4-27 08:18 来自手机 | 只看该作者
lon7085 发表于 2019-6-28 22:49
因每个人用的板子可能都不太相同,程序上一些接口就要修改,不能完全照单直接烧入单片机中,用的晶振不同时 ...

可以发一个给我吗?谢谢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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