打印
[范例教程]

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

[复制链接]
327|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
rosemoore|  楼主 | 2023-7-16 08:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<intrins.h>

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

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

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


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

        i = 11;
        while (--i);
}


void Delay20ms()                //@11.0592MHz
{
        unsigned char i, j;

        i = 36;
        j = 217;
        do
        {
                while (--j);
        } while (--i);
}


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

        _nop_();
        i = 8;
        j = 1;
        k = 243;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}


/*********************************************************************************************
函数名:DHT11启动函数
调  用:无
参  数:无
返回值:无
结  果:DHT11开始工作
备  注:
**********************************************************************************************/
void DHT11_start()                 // 主机控制DHT11开始工作
{
   DATA=1;                                 // 主线空闲状态
   _nop_();
   _nop_();
   DATA=0;                                 // 主机发送开始工作信号
   Delay20ms();   //延时18ms以上
   DATA=1;                                 // 拉高并延时等待DHT11响应
   Delay30us();
}
/*********************************************************************************************
函数名:DHT11读数据函数
调  用:? = DHT11_rec_byte();
参  数:无
返回值:
结  果:读DHT11数据并保存到dat
备  注:
**********************************************************************************************/

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

/*********************************************************************************************
函数名:接收DHT11的40位的数据并校验
调  用:? = DHT11_receive();
参  数:无
返回值:无
结  果:结果保存到dat_r[i]中
备  注:
**********************************************************************************************/
void DHT11_receive()      //接收40位的数据
{
    uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
    DHT11_start();                 // 主机控制DHT11开始工作
    if(DATA==0)
    {
        while(DATA==0);   //等待拉高     
        Delay30us();
                Delay30us();
                Delay30us();  //拉高后延时80us
        R_H=DHT11_rec_byte();    //接收湿度高八位  
        R_L=DHT11_rec_byte();    //接收湿度低八位  
        T_H=DHT11_rec_byte();    //接收温度高八位  
        T_L=DHT11_rec_byte();    //接收温度低八位
        revise=DHT11_rec_byte(); //接收校正位

        Delay30us();    //结束

        if((R_H+R_L+T_H+T_L)==revise)      //校正
        {
            RH=R_H;
            RL=R_L;
            TH=T_H;
            TL=T_L;
        }
        /*数据处理,方便显示*/
        dat_r[0]='0'+(RH/10);
        dat_r[1]='0'+(RH%10);
        dat_r[2]='0'+(TH/10);
        dat_r[3]='0'+(TH%10);
    }
}

/********************************************************************
* 名称 : bit Busy(void)
* 功能 : 这个是一个读状态函数,读出函数是否处在忙状态
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void Busy(void)
{
bit busy_flag = 1;
IODATA  = 0xff;
RS = 0;          //指令关
Delay30us();
RW = 1;          //读状态
Delay30us();
E = 1;        //使能高电平
while(1)
{
busy_flag = (bit)(IODATA  & 0x80); //强制取最高位
if(busy_flag == 0)
{
break;
}
}
E = 0;           //E 1->0,rs=0,rw=1,
           //将数据寄存器内的数据读到DB0~DB7,分别将状态标志BF和地址计数器(AC)内容读到DB7和DB6~DB0。

}

/********************************************************************
* 名称 : lcd1602_write_cmd(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/
void lcd1602_write_cmd(uchar del)
{
RS = 0;
Delay30us();
RW = 0;
Delay30us();
E = 0;
Delay30us();
IODATA  = del;
Delay30us();
E = 1;
Delay30us();
E = 0;                        //E 1->0,rs=0,rw=0, 将指令代码写入指令寄存器中
}

/********************************************************************
* 名称 : lcd1602_write_data(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/

void lcd1602_write_data(uchar del)
{
Busy();      
Delay30us();
RS = 1;
Delay30us();
RW = 0;
Delay30us();
E = 0;
Delay30us();
IODATA  = del;
Delay30us();
E = 1;
Delay30us();
E = 0;                          //E 1->0,rs=1,rw=0, 数据写入数据寄存器中
}

/********************************************************************
* 名称 : lcd1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void lcd1602_init(void)
{
Delay20ms();
lcd1602_write_cmd(0x38);         //8位数据,双列,5*7字形
Delay20ms();
lcd1602_write_cmd(0x38);
Delay20ms();
lcd1602_write_cmd(0x38);
Busy();
lcd1602_write_cmd(0x08);// 只开显示
Busy();   
lcd1602_write_cmd(0x01);        //清屏
Busy();
lcd1602_write_cmd(0x06);//显示地址递增,即写一个数据后,显示位置右移一位
Busy();
lcd1602_write_cmd(0x0c);        //开启显示屏,关光标,光标不闪烁
}

/********************************************************************
* 名称 : lcd1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void lcd1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1)
{
a = 0x80;
}
if(hang == 2)
{
a = 0xc0;
}
a = a + lie - 1;
Busy();
lcd1602_write_cmd(a);  //置数据存贮器地址
Busy();
lcd1602_write_data(sign);
}

/********************************************************************
* 名称 : lcd1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void lcd1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1)
{
a = 0x80;
}
if(hang == 2)
{
a = 0xc0;
}
a = a + lie - 1;
while(1)
{
Busy();
lcd1602_write_cmd(a);
Busy();
lcd1602_write_data(*p);
a++;
p++;   
if((*p == '\0')||(a==0x90)||(a==0xd0)) //字符结束或每行最后一个字符
{
break;
}
}
}

/*********************************************************************************************
函数名:主函数
调  用:无
参  数:无
返回值:无
结  果:读DHT11数据并送到1602显示
备  注:
**********************************************************************************************/
void main (void)
{
        
        Delay20ms();
        lcd1602_init();                //LCD初始化
        while(1)
        {
                Delay1s();                //经测试,两次连读要至少延时80ms        
                DHT11_receive();//接受数据
                lcd1602_string(1,1,"SHIDU:");
                lcd1602_string(2,1,"WENDU:");
                lcd1602_char(1,7,dat_r[0]);
                lcd1602_char(1,8,dat_r[1]);
                lcd1602_char(2,7,dat_r[2]);
                lcd1602_char(2,8,dat_r[3]);
                lcd1602_string(1,9,"%");
                lcd1602_char(2,9,0XDF);
                lcd1602_string(2,10,"C");
               
        }
}


使用特权

评论回复
沙发
weifeng90| | 2023-7-17 08:30 | 只看该作者
还有用1602显示屏的吗?

使用特权

评论回复
板凳
jf101| | 2023-7-24 13:39 | 只看该作者
weifeng90 发表于 2023-7-17 08:30
还有用1602显示屏的吗?

这种小屏确实用的比较少了,建议还是使用LCD的吧

使用特权

评论回复
地板
小小蚂蚁举千斤| | 2023-7-25 09:46 | 只看该作者
很经典的样例程序尤其是1602

使用特权

评论回复
5
小夏天的大西瓜| | 2023-7-25 10:16 | 只看该作者
1602液晶的案例还是挺多的

使用特权

评论回复
6
OKAKAKO| | 2023-7-25 13:06 | 只看该作者
DHT11温湿度计使用IIC通信的嘛?

使用特权

评论回复
7
LOVEEVER| | 2023-7-26 17:45 | 只看该作者
DHT11温湿度具体硬件参数有吗

使用特权

评论回复
8
linfelix| | 2023-8-7 07:36 | 只看该作者
DHT11检测温湿度求教              

使用特权

评论回复
9
geraldbetty| | 2023-8-7 08:20 | 只看该作者
dht11温度传感器显示屏不亮怎么回事

使用特权

评论回复
10
biechedan| | 2023-8-7 08:26 | 只看该作者
在读取DHT11传感器的温湿度数据后,需要进行适当的数据处理和格式化,以便在液晶显示屏上进行正确的显示。

使用特权

评论回复
11
wangdezhi| | 2023-8-7 19:45 | 只看该作者
在使用1602液晶显示屏之前,需要进行初始化设置。这通常包括设置显示模式、光标和光标闪烁等。

使用特权

评论回复
12
lihuami| | 2023-8-7 21:56 | 只看该作者
DHT11传感器具有一定的响应时间,通常建议在两次读取之间留出适当的延迟时间,以确保传感器有足够的时间完成测量和数据更新。

使用特权

评论回复
13
plsbackup| | 2023-8-9 15:38 | 只看该作者
在读取DHT11的数据之前,需要适当的延时以确保传感器完成数据采集和转换

使用特权

评论回复
14
hilahope| | 2023-8-14 09:06 | 只看该作者
DHT11的精度可能会受到环境条件和其他因素的影响

使用特权

评论回复
15
adolphcocker| | 2023-8-14 13:21 | 只看该作者
应用中可能需要进行温湿度校准。可以通过与其他已知准确度的传感器进行比较或使用校准算法来调整读取到的数据。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

42

主题

1135

帖子

2

粉丝