找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 786|回复: 6
收起左侧

lcd1602温湿度检测一直为0

[复制链接]
ID:1119185 发表于 2024-5-3 18:59 | 显示全部楼层 |阅读模式
975727962256121.jpg
  1. #include "reg52.h"
  2. #include <intrins.h>
  3. #include <string.h>

  4. #define dataBuf P0

  5. sfr AUXR = 0x8e;

  6. sbit RS = P1^0;
  7. sbit RW = P1^1;
  8. sbit EN = P1^2;
  9. sbit dht11 = P1^3;

  10. char dht11Data[5];
  11. char temperature[9];
  12. char humidity[9];

  13. void Delay40us()                //@11.0592MHz
  14. {
  15.         unsigned char i;

  16.         _nop_();
  17.         i = 15;
  18.         while (--i);
  19. }

  20. void Delay5ms()                //@11.0592MHz
  21. {
  22.         unsigned char i, j;

  23.         i = 9;
  24.         j = 244;
  25.         do
  26.         {
  27.                 while (--j);
  28.         } while (--i);
  29. }

  30. void Delay15ms()                //@11.0592MHz
  31. {
  32.         unsigned char i, j;

  33.         i = 27;
  34.         j = 226;
  35.         do
  36.         {
  37.                 while (--j);
  38.         } while (--i);
  39. }

  40. void Delay30ms()                //@11.0592MHz
  41. {
  42.         unsigned char i, j;

  43.         i = 54;
  44.         j = 199;
  45.         do
  46.         {
  47.                 while (--j);
  48.         } while (--i);
  49. }

  50. void Delay1000ms()                //@11.0592MHz
  51. {
  52.         unsigned char i, j, k;

  53.         _nop_();
  54.         i = 8;
  55.         j = 1;
  56.         k = 243;
  57.         do
  58.         {
  59.                 do
  60.                 {
  61.                         while (--k);
  62.                 } while (--j);
  63.         } while (--i);
  64. }

  65. //配置DHT11输出数据
  66. void dht11Start()
  67. {
  68.         dht11 =  1;
  69.         dht11 = 0;
  70.         Delay30ms();
  71.         dht11 = 1;
  72.         while(dht11);  //等待自己拉到低电平
  73.         while(!dht11);  //等待自己拉到高电平
  74.         while(dht11);  //等待自己拉到低电平
  75. }

  76. //获取DHT11的数据
  77. void obtainDht11Data()
  78. {
  79.         int i,j;
  80.         char tmp;
  81.         char flag;
  82.         dht11Start();  //开始输出数据
  83.         for (i = 0; i < 5; i++){  //总共获取5个字符(40bit)的数据
  84.                 for (j = 0; j < 8; j++){  
  85.                         //一次获取一个bit数据
  86.                         while(!dht11);  //等待自己拉到高电平
  87.                         Delay40us();  //高电平时间为27微秒左右表示0,高电平时间为70微秒左右表示1
  88.                        
  89.                         if(dht11 == 1){  //40微秒后为高电平即输出1
  90.                                 while(dht11);
  91.                                 flag = 1;
  92.                         }else{  //40微秒后为低电平即输出0
  93.                                 flag = 0;
  94.                         }
  95.                         tmp = tmp << 1;  //由于dht11的数据是高位先出,所以用左移的方式
  96.                         tmp = tmp | flag;  //(|1成1,|0不变),即对于前面7个bit,flag都为0,不改变tmp的值
  97.                 }
  98.                 dht11Data[i] = tmp;
  99.         }
  100.        

  101. }

  102. //发送数据到字符数组,用于LCD1602显示
  103. void sendStrData()
  104. {
  105.         humidity[0] = 'H';
  106.         humidity[1] = ':';
  107.         humidity[2] = dht11Data[0]/10 + 0x30;
  108.         humidity[3] = dht11Data[0]%10 + 0x30;
  109.         humidity[4] = '.';
  110.         humidity[5] = dht11Data[1]/10 + 0x30;
  111.         humidity[6] = dht11Data[1]%10 + 0x30;
  112.         humidity[7] = '%';
  113.         humidity[8] = '\0';
  114.         temperature[0] = 'T';
  115.         temperature[1] = ':';
  116.         temperature[2] = dht11Data[2]/10 + 0x30;
  117.         temperature[3] = dht11Data[2]%10 + 0x30;
  118.         temperature[4] = '.';
  119.         temperature[5] = dht11Data[3]/10 + 0x30;
  120.         temperature[6] = dht11Data[3]%10 + 0x30;
  121.         temperature[7] = 'C';
  122.         temperature[8] = '\0';
  123. }

  124. //检测忙信号,读数据线的D7位
  125. void checkBusySignal()
  126. {
  127.         char tmp = 0x80;
  128.         dataBuf = 0x80;
  129.         while(tmp & 0x80){  //当忙标志位(数据位D7)为高电平时,此时模块不能接收命令或者数据
  130.                 RS = 0;
  131.                 RW = 1;
  132.                 EN = 0;
  133.                 _nop_();
  134.                 EN = 1;
  135.                 _nop_();
  136.                 _nop_();
  137.                 tmp = dataBuf;  //读八位数据线的数据,当不忙时,硬件会自动将该位置0,当检测到D7为低电平时将退出死循环
  138.                 EN = 0;
  139.                 _nop_();
  140.         }
  141. }

  142. //写指令
  143. void writeCmd(char cmd)
  144. {
  145.         checkBusySignal();
  146.         RS = 0;  //选择写指令寄存器
  147.         RW = 0;
  148.         EN = 0;
  149.         _nop_();  //该函数为延时函数,延时一微秒
  150.         dataBuf = cmd;  //将指令存入八位数据线中
  151.         EN = 1;
  152.         _nop_();
  153.         _nop_();
  154.         EN = 0;
  155.         _nop_();
  156. }

  157. //写数据
  158. void writeData(char myData)
  159. {
  160.         checkBusySignal();
  161.         RS = 1;  //选择写数据寄存器
  162.         RW = 0;
  163.         EN = 0;
  164.         _nop_();  //该函数为延时函数,延时一微秒
  165.         dataBuf = myData;  //将数据存入八位数据线中
  166.         EN = 1;
  167.         _nop_();
  168.         _nop_();
  169.         EN = 0;
  170.         _nop_();
  171. }

  172. //LCD1602初始化
  173. void lcd1602Init()
  174. {
  175.         Delay15ms();  //延时 15ms
  176.         writeCmd(0x38);  //写指令 38H(不检测忙信号)
  177.         Delay5ms();  //延时 5ms
  178.         checkBusySignal();//以后每次写指令,读/写数据操作均需要检测忙信号
  179.         writeCmd(0x38);  //写指令 38H:显示模式设置
  180.         writeCmd(0x08);  //写指令 08H:显示关闭
  181.         writeCmd(0x01);  //写指令 01H:显示清屏
  182.         writeCmd(0x06);  //写指令 06H:显示光标移动设置
  183.         writeCmd(0x0C);  //写指令 0CH:显示开及光标设置
  184. }

  185. //LCD1602显示一行字符
  186. void lcd1602ShowData(char rows,char columns,char *str)
  187. {
  188.         switch (rows){  //选择行
  189.         case 1:
  190.                 writeCmd(0x80 + columns);  //选择列
  191.                 while(*str != '\0'){
  192.                         writeData(*str);  //显示字符
  193.                         str++;
  194.                 }
  195.                 break;

  196.         case 2:
  197.                 writeCmd(0x80 + 0x40 +columns);  //选择列
  198.                 while(*str != '\0'){
  199.                         writeData(*str);  //显示字符
  200.                         str++;
  201.                 }
  202.                 break;

  203.         default:
  204.                 break;
  205.         }
  206. }

  207. void main()
  208. {
  209.         lcd1602Init();
  210.         //dht11上电后,需要延时1-2s度过不稳定状态
  211.         Delay1000ms();
  212.         Delay1000ms();
  213.        
  214.         //每1s获取空气中的温湿度
  215.         while(1){
  216.                 obtainDht11Data();  
  217.                 sendStrData();
  218.                 lcd1602ShowData(2,0,humidity);
  219.                 lcd1602ShowData(1,0,temperature);
  220.                 Delay1000ms();
  221.         }
  222. }
复制代码

回复

使用道具 举报

ID:155507 发表于 2024-5-4 11:12 | 显示全部楼层
延时时间不对
序不对


给一个你参考。
  1. void DHT11_Start()
  2. {
  3.         DATA=1;                        //空闲状态为高电平
  4.         delay_us(2);
  5.         DATA=0;                        //主机发出开始信号,将总线拉低至少18ms
  6.         delay_ms(20);
  7.         DATA=1;                        //拉高总线并延时等待20--40us
  8.         delay_us(30);
  9. }

  10. uchar Receive_Byte()        //读取一个字节数据
  11. {
  12.         uchar i,dat;
  13.         for(i=0;i<8;i++)
  14.         {
  15.                 while(DATA==0);        //等待数据低电平部分过去
  16.                 delay_us(8);        //延时50us,若DATA还为高电平则为数据1,否则为数据0
  17.                 dat<<=1;
  18.                 if(DATA==1)
  19.                 {
  20.                         dat|=0x01;
  21.                 }
  22.                 while(DATA==1);        //等待此帧数据高电平完全过去
  23.         }
  24.         return dat;
  25. }

  26. void DHT11_ReadData()
  27. {
  28.         uchar H1,H2,T1,T2,check,Humanity_H,Humanity_L,Temperature_H,Temperature_L;
  29.         DHT11_Start();                //主机发出开始信号
  30.         if(DATA==0)                        //DHT11响应信号
  31.         {
  32.                 while(DATA==0);        //DHT11响应信号,80us
  33.                 delay_us(40);        //DHT11响应信号,拉高延时80us,准备输出
  34.                 H1=Receive_Byte();
  35.                 H2=Receive_Byte();
  36.                 T1=Receive_Byte();
  37.                 T2=Receive_Byte();
  38.                 check=Receive_Byte();
  39.                 delay_us(25);        //当一次数据传输完成后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。
  40.                 if((H1+H2+T1+T2)==check)        //数据检验
  41.                 {
  42.                         Humanity_H=H1;
  43.                         Humanity_L=H2;
  44.                         Temperature_H=T1;
  45.                         Temperature_L=T2;
  46.                 }
  47.                 DHT11_Data[0]=Humanity_H/10;
  48.                 DHT11_Data[1]=Humanity_H%10;
  49.                 DHT11_Data[2]=Humanity_L/10;
  50.                 DHT11_Data[3]=Humanity_L%10;
  51.                 DHT11_Data[4]=Temperature_H/10;
  52.                 DHT11_Data[5]=Temperature_H%10;
  53.                 DHT11_Data[6]=Temperature_L/10;
  54.                 DHT11_Data[7]=Temperature_L%10;
  55.         }
  56. }

复制代码













回复

使用道具 举报

ID:1119185 发表于 2024-5-4 13:58 | 显示全部楼层
angmall 发表于 2024-5-4 11:12
延时时间不对
时序不对

谢谢,我看一下
回复

使用道具 举报

ID:619259 发表于 2024-5-4 15:28 | 显示全部楼层
纠正一下:lcd1602不能检测温湿度,这个功能是由温湿度传感器DHT11完成的。
回复

使用道具 举报

ID:1119185 发表于 2024-5-6 15:26 | 显示全部楼层
li_z 发表于 2024-5-4 13:58
谢谢,我看一下

你好,您能否具体一些,我试过了,目前还未解决,如果可以,,交流一下
回复

使用道具 举报

ID:226055 发表于 2024-5-6 20:11 | 显示全部楼层
    DHT11温湿度传感器信号线上需要加上拉电阻的,不知道你硬件上有没有加呢。
回复

使用道具 举报

ID:1119185 发表于 2024-5-7 16:24 | 显示全部楼层
cocolala 发表于 2024-5-6 20:11
DHT11温湿度传感器信号线上需要加上拉电阻的,不知道你硬件上有没有加呢。

我连接的是P2口,内部有上拉电阻
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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