找回密码
 立即注册

QQ登录

只需一步,快速开始

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

lcd1602加dh11显示温湿度

[复制链接]
跳转到指定楼层
楼主
ID:1160989 发表于 2025-10-7 09:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在网上找了好多代码都不能运行,有的讲原理有的驱动起来有问题,对小白太不友好,找了好久终于找到能用的驱动,感谢b站大神毛毛雨分享dh11.c
#include "dht11.h"

/**********************************
*函数名:DHT11_start
*函数功能:DHT11开始信号
*输入:无
*输出:无
***********************************/
void DHT11_start()
{
   Data = 1;
   DelayUs(2);
   Data = 0;
   DelayMs(30);  //主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号
   Data = 1;
         DelayUs(15);        //15*2+5=35us主机发送开始信号结束后,延时等待20-40us后,读取DHT11的响应信号
}

/*******************************************
*函数名:DHT11_rec_byte
*函数功能:接收8位二进制
*输入:无
*输出:dat
**********************************************/
uchar DHT11_rec_byte()      
{
   uchar i,dat=0;
   for(i=0;i<8;i++)   
   {         
      while(!Data);   //每一bit数据都以50us低电平时隙开始,等待拉高
                  DelayUs(20);    //0-高电平持续26~28us;1-高电平持续116~118us,
//此处延时时间过长会死循环,过短读出的数据不正确
//(仿真中偏大255,根据仿真情况调整时长;实物中会出现不随环境变化或部分变化的情况)
      dat <<= 1;        //位读取先高后低   
      if(Data == 1)   
         dat += 1;
      while(Data);     
    }
    return dat;
}
/**********************************************
*函数名:DHT11_receive
*函数功能:接收40位的数据
*输入:无
*输出:结构体dht11_t,含温度湿度整数和小数部分
**********************************************/
dht11_t DHT11_receive(void)     
{
    uchar R_H,R_L,T_H,T_L,revise;
                dht11_t dht11;       
    DHT11_start();

    if(Data == 0)
    {
        while(Data == 0);                                 //等待DHT11拉高
                                DelayUs(38);                                   //等待80us DHT11发送数据   
        R_H=DHT11_rec_byte();            //接收湿度高八位   
        R_L=DHT11_rec_byte();            //接收湿度低八位   
        T_H=DHT11_rec_byte();            //接收温度高八位   
        T_L=DHT11_rec_byte();            //接收温度低八位   
        revise=DHT11_rec_byte();         //接收校正位                 
                                if(revise == (R_H+R_L+T_H+T_L))
                                {                               
                                //温度整数部分
                                        dht11.temp_i = T_H;                                                                
                                        //温度小数部分
                                        dht11.temp_d = T_L;                               
                                        //湿度整数部分
                                        dht11.humi_i = R_H;
                                        //湿度小数部分
                                        dht11.humi_d = R_L;
                                }
                                DelayUs(23); //拉低总线50us,随后总线由上拉电阻进入空闲状态
    }         
                return dht11;
}
///////////////////////////////////////////////////

dh11.h

#ifndef __DHT11_H__
#define __DHT11_H__

#include "delay.h"
#include <reg51.h>

//注意:
//DHT11一次通讯时间最大3ms,主机连续采样间隔建议不小于100ms,最好2秒以上。

sbit Data = P3^2;
#define uchar unsigned char
#define uint unsigned int
typedef struct {
        uchar temp_i;
        uchar temp_d;
        uchar humi_i;
        uchar humi_d;
}dht11_t;
void DHT11_start();
uchar DHT11_rec_byte();
dht11_t DHT11_receive(void) ;
#endif


1602.c

#include "1602.h"
#include "delay.h"
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

/*******************************************
函数名称:LcdReset
功    能:对1602液晶模块进行复位操作
参    数:无
返回值  :无
使用方法:初始化1
********************************************/
void LcdReset(void)
{
    DelayMs(50);
    LcdWriteCommand(0x38, 1);                //显示模式设置
    LcdWriteCommand(0x08, 1);                //显示关闭
    LcdWriteCommand(0x01, 1);          //显示清屏,光标加左上角
    LcdWriteCommand(0x06, 1);                //写字符时整体不移动,地址指针及光标+1
    LcdWriteCommand(0x0c, 1);                //显示开,不开游标,不闪烁
}       

/*********************************************
功    能:清屏
参    数:无
返回值  :无
使用方法:初始化2或必要时使用
*********************************************/
void LcdClear(void)
{
        LcdWriteCommand(0x01,1);
        DelayMs(5);
}


/*******************************************
函数名称:Disp1Char
功    能:在某个位置显示一个字符
参    数:x--列坐标
          y--行坐标
          data--显示的字符
返回值  :无
********************************************/
void Disp1Char(uchar x,uchar y,uchar Data)
{
    PosXY( x, y );                       
    LcdWriteData( Data );               
}

/************************************************************************
函数名称:DispStr
功    能:从某个位置起连续显示一个字符串,一行结束,不再显示
参    数:x--列坐标
          y--行坐标
          Str--待显示的字符串指针/数组
返回值  :无
*************************************************************************/
void DispStr(uchar x,uchar y,uchar *Str)
{
    uchar *temp;
    uchar i,n = 0;

    temp = Str;
    while(*Str++ != '\0')   n++;//计算字符的个数n

    for (i=0;i<n;i++)
    {
        Disp1Char(x++,y,temp);//在同一行逐个显示
        if (x == 0x10)//一行结束,不再显示
        {
            break;
        }
    }
}
/**************************************************************************
函数名称:DispNchar
功    能:从某个位置起连续显示N个字符,一行结束,继续换行或从头显示
参    数:x--列坐标
          y--行坐标
          n--字符个数
          str--指向字符存放位置的指针
返回值  :无
**************************************************************************/
void DispNChar(uchar x,uchar y, uchar n,uchar *str)
{
    uchar i;

    for (i=0;i<n;i++)
    {
        Disp1Char(x++,y,str);//在同一行逐个显示
        if (x == 0x10)//一行结束,继续换行或从头显示
        {
           x = 0;
           y ^= 1;
        }
    }
}
/*******************************************
函数名称:PosXY
功    能:输入显示字符坐标信息
参    数:x--列坐标
          y--行坐标
返回值  :无
********************************************/
void PosXY(uchar x,uchar y)
{
    uchar temp;

    temp = x&0x0f;
    y &= 0x01;
    if(y)   temp |= 0x40;  //如果在第2行
    temp |= 0x80;

    LcdWriteCommand(temp,1);
}

/*******************************************
函数名称:LcdWriteCommand
功    能:写入命令
参    数:cmd--命令,
          chk--是否判忙的标志,1:判忙,0:不判
返回值  :无
********************************************/
void LcdWriteCommand(uchar cmd, uchar chk)
{

    if (chk) WaitForEnable();   // 检测忙信号,仿真时可屏蔽

    RS = 0;       
    RW = 0;
    _nop_();

    DataPort = cmd;             //将命令字写入数据端口
    _nop_();                                       

    EN = 1;                     //产生使能脉冲信号
    _nop_();
    _nop_();
    EN = 0;                       
}

/*******************************************
函数名称:LcdWriteData
功    能:向当前地址写入显示数据
参    数:data--显示字符数据
返回值  :无
********************************************/
void LcdWriteData( uchar Data )
{
    WaitForEnable();        //等待液晶不忙
    RS = 1;
    RW = 0;
       
    EN = 1;       
                _nop_();
    DataPort = Data;        //将显示数据写入数据端口               
    _nop_();//产生使能脉冲信号
    _nop_();
    _nop_();
    EN = 0;               
}

/*******************************************
函数名称:WaitForEnable
功    能:等待1602液晶完成内部操作或超时跳出
参    数:无
返回值  :无
********************************************/
void WaitForEnable(void)
{
          unsigned int later=0;
                DataPort=0xff;
    RS = 0;
    RW = 1;
    _nop_();
    EN = 1;
    _nop_();
    _nop_();  
    while(((DataPort&0x80)!=0)&&(later<1000))  //检测忙标志
    {
      DelayUs(2);
      later++;        
    }
    EN = 0;
}               



1602.h


#ifndef __LCD1602_H__
#define __LCD1602_H__
/************************************************************************/
#include<reg51.h>
#include<intrins.h>

sbit RS = P2^6;   //定义端口
sbit RW = P2^5;
sbit EN = P2^7;

#define DataPort    P0
/*******************************************
函数名称:LcdReset
功    能:对1602液晶模块进行复位操作
参    数:无
返回值  :无
使用方法:初始化1
********************************************/
void LcdReset(void);

/*********************************************
功    能:清屏
参    数:无
返回值  :无
使用方法:初始化2或必要时使用
*********************************************/
void LcdClear(void);

/*******************************************
函数名称:Disp1Char
功    能:在某个位置显示一个字符
参    数:x--列坐标0-15
          y--行坐标0-1
          data--显示的字符
返回值  :无
********************************************/
void Disp1Char(unsigned char x,unsigned char y,unsigned char Data);

/*****************************************************************
函数名称:DispStr
功    能:从某个位置起连续显示一个字符串,一行结束,不再显示
参    数:x--列坐标
          y--行坐标
          Str--待显示的字符串指针/数组
返回值  :无
*****************************************************************/
void DispStr(unsigned char x,unsigned char y,unsigned char *str);

/****************************************************************
函数名称:DispNchar
功    能:从某个位置起连续显示N个字符,一行结束,继续换行或从头显示
参    数:x--列坐标
          y--行坐标
          n--字符个数
          str--指向字符存放位置的指针
返回值  :无
**************************************************************************/
void DispNChar(unsigned char x,unsigned char y, unsigned char n,unsigned char *str);


//以下为函数内部调用

/*********************************************
函数名称:PosXY
功    能:输入显示字符坐标信息
参    数:x--列坐标
          y--行坐标
返回值  :无
**********************************************/
void PosXY(unsigned char x,unsigned char y);

/*******************************************
函数名称:LcdWriteCommand
功    能:写入命令
参    数:cmd--命令,
          chk--是否判忙的标志,1:判忙,0:不判
返回值  :无
********************************************/
void LcdWriteCommand(unsigned char cmd,unsigned char chk);

/*******************************************
函数名称:LcdWriteData
功    能:向当前地址写入显示数据
参    数:data--显示字符数据
返回值  :无
********************************************/
void LcdWriteData( unsigned char Data);

/*******************************************
函数名称:WaitForEnable
功    能:等待1602液晶完成内部操作或超时跳出
参    数:无
返回值  :无
********************************************/
void WaitForEnable(void);

#endif



delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void DelayUs(unsigned char t);
void DelayMs(unsigned int t);

#endif


delay.c

#include "delay.h"

/*------------------------------------------------
                 us延时函数
                 输入参数: unsigned char t
                 无返回值
                 晶振12M
                 实际延时时间= t*2 + 5 us
------------------------------------------------*/
void DelayUs(unsigned char t)
{   
while(--t);
}
/*------------------------------------------------
                         ms延时函数
                        含有输入参数 unsigned int t
                        无返回值
                        晶振12M
------------------------------------------------*/
void DelayMs(unsigned int z)
{     
        unsigned int i,j;
  for(i=z;i>0;i--)
      for(j=123;j>0;j--);
}



wenshidu.rar (4.12 KB, 下载次数: 0)




评分

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

查看全部评分

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

使用道具 举报

沙发
ID:997011 发表于 2025-10-8 07:16 | 只看该作者
用arduino开发板写程序很简单.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <dht11.h>
dht11 DHT11;
#define DHT11PIN 8
LiquidCrystal_I2C lcd(0x3f,16,2);
void setup(){
   Wire.begin();
  Serial.begin(9600);
lcd.init();  
  lcd.backlight();
}
void loop(){
   int chk = DHT11.read(DHT11PIN);
    lcd.setCursor(0,0);
    lcd.print("Temp:");
    lcd.setCursor(8,0);
    lcd.print((float)DHT11.temperature, 1);
    lcd.setCursor(14,0);
    lcd.print((char)223);//显示o符号
    lcd.setCursor(15,0);
    lcd.print("C:");
    lcd.setCursor(0,1);
    lcd.print("Humi:");
    lcd.setCursor(9,1);
    lcd.print((float)DHT11.humidity, 0);
    lcd.setCursor(15,1);
    lcd.print((char)37);//显示%符号
  delay(1000);
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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