找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机DHT11在LCD1602上显示+报警+运行时间 源程序

[复制链接]
跳转到指定楼层
楼主
要求如下:
(1)用温湿度模块采集当前环境的温度和湿度,并在LCD上显示;
(2)用按键可以设定一个温度范围,当前温度不在所设置的温度范围内时,LED闪动报警,当温度在设定温度范围内时,停止报警;
(3)用按键可以设定一个湿度范围,当前湿度不在所设置的湿度范围内时,LED闪动报警,当湿度在设定湿度范围内时,停止报警;
(4)LCD上能正确显示当前温度、湿度、设定温度、设定湿度;
(5)显示系统持续工作的时间,从系统上电开始计时,到目前为止,总共运行了多少时间,格式为“HH:MM:SS”。

完成情况:
(1)LCD上显示--------完成
(2)设定温湿度范围---完成(k1:界面切换  k2:数值加  k3:数值减)
(3)显示持续时间-----完成



LCD1602.h

#include "reg51.h"
#ifndef __LCD1602_H_
#define __LCD1602_H_
#define LCD1602_DATAPINS  P0
typedef unsigned char uchar;
typedef unsigned int uint;

sbit DATA=P2^0;   //定义数据线
sbit LCD1602_RS=P2^6; //定义rs端口
sbit LCD1602_RW=P2^5; //定义rw端口
sbit LCD1602_E=P2^7; //定义en端口

void LcdWriteCom(uchar com);
void LcdWriteData(uchar dat);
void LcdInit();


#endif



LCD1602.c
#include "led1602.h"

/*******************************************************************************
* 函 数 名         : Lcd1602_Delay1ms
* 函数功能                   : 延时函数,延时1ms
* 输    入         : c
* 输    出         : 无
* 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/

void Lcd1602_Delay1ms(uint c)   //误差 0us
{
    uchar a,b;
        for (; c>0; c--)
        {
                 for (b=199;b>0;b--)
                 {
                          for(a=1;a>0;a--);
                 }      
        }
            
}

/*******************************************************************************
* 函 数 名         : LcdWriteCom
* 函数功能                   : 向LCD写入一个字节的命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/
#ifndef         LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
void LcdWriteCom(uchar com)          //写入命令
{
        LCD1602_E = 0;     //使能
        LCD1602_RS = 0;           //选择发送命令
        LCD1602_RW = 0;           //选择写入
        
        LCD1602_DATAPINS = com;     //放入命令
        Lcd1602_Delay1ms(1);                //等待数据稳定

        LCD1602_E = 1;                  //写入时序
        Lcd1602_Delay1ms(5);          //保持时间
        LCD1602_E = 0;
}
#else
void LcdWriteCom(uchar com)          //写入命令
{
        LCD1602_E = 0;         //使能清零
        LCD1602_RS = 0;         //选择写入命令
        LCD1602_RW = 0;         //选择写入

        LCD1602_DATAPINS = com;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;         //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;

        LCD1602_DATAPINS = com << 4; //发送低四位
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;         //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名         : LcdWriteData
* 函数功能                   : 向LCD写入一个字节的数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/                  
#ifndef         LCD1602_4PINS                  
void LcdWriteData(uchar dat)                        //写入数据
{
        LCD1602_E = 0;        //使能清零
        LCD1602_RS = 1;        //选择输入数据
        LCD1602_RW = 0;        //选择写入

        LCD1602_DATAPINS = dat; //写入数据
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;   //写入时序
        Lcd1602_Delay1ms(5);   //保持时间
        LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)                        //写入数据
{
        LCD1602_E = 0;          //使能清零
        LCD1602_RS = 1;          //选择写入数据
        LCD1602_RW = 0;          //选择写入

        LCD1602_DATAPINS = dat;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;          //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;

        LCD1602_DATAPINS = dat << 4; //写入低四位
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;          //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名       : LcdInit()
* 函数功能                 : 初始化LCD屏
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/                  
#ifndef                LCD1602_4PINS
void LcdInit()                                                  //LCD初始化子程序
{
         LcdWriteCom(0x38);  //开显示
        LcdWriteCom(0x0c);  //开显示不显示光标
        LcdWriteCom(0x06);  //写一个指针加1
        LcdWriteCom(0x01);  //清屏
        LcdWriteCom(0x80);  //设置数据指针起点
}
#else
void LcdInit()                                                  //LCD初始化子程序
{
        LcdWriteCom(0x32);         //将8位总线转为4位总线
        LcdWriteCom(0x28);         //在四位线下的初始化
        LcdWriteCom(0x0c);  //开显示不显示光标
        LcdWriteCom(0x06);  //写一个指针加1
        LcdWriteCom(0x01);  //清屏
        LcdWriteCom(0x80);  //设置数据指针起点
}
#endif

main.c
/********************************************************************************************************/
#include<reg51.h>
#include<intrins.h>
#include<led1602.h>

#define uchar unsigned char        //无符号字符型类型数据
#define uint unsigned int //无符号整型数据
sbit led=P2^2;
sbit k1=P3^1;
sbit k2=P3^2;
sbit k3=P3^3;
uchar dat_r[4];          //用于存放从DHT11读取到的数值
uchar num[]="0123456789";
uchar Disp[]="RTHC%·";
uint i,j,k;
uchar hrh=80,lrh=40,hth=20,lth=5;
uchar c[8];
uchar b[8],shi,fen,miao;
uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
void Timer0Init();


/*********************************************************************************************
函数名:延时函数
调  用:Delay30us();/Delay20ms();/Delay1s();
参  数:无
返回值:无
结  果:延时相应时间
备  注:振荡晶体为11.0592MHz(所有延时函数Copy自STC-ISP(v6.85).exe)
**********************************************************************************************/
void delay(uint i)
{
        while(i--);
}
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位的数据
{

    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);
    }
}

void Timer0Init()
{
        TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。

        TH0=0Xd8;        //给定时器赋初值,定时10ms
        TL0=0Xf0;        
        TR0=1;//打开定时器                        
}

void timepros()
{
        b[0]=num[shi/10];
        b[1]=num[shi%10];
        b[2]=0x3a;
        b[3]=num[fen/10];
        b[4]=num[fen%10];
        b[5]=0x3a;
        b[6]=num[miao/10];
        b[7]=num[miao%10];
        

}

void secondtimepros()
{
  c[0]=num[lrh/10];
        c[1]=num[lrh%10];
        c[2]=num[hrh/10];
        c[3]=num[hrh%10];
        c[4]=num[lth/10];
        c[5]=num[lth%10];
        c[6]=num[hth/10];
        c[7]=num[hth%10];
}

void keyprosA()
{
        if(k1==0) //检测按键 K1 是否按下
        {
                delay(1000); //消除抖动 一般大约 10ms
                if(k1==0) //再次判断按键是否按下
                {
                        i++; //led 状态取反
                        LcdWriteCom(0x01);
                }
                while(!k1); //检测按键是否松开
               
        }

}
void keyprosB()
{
        if(k2==0) //检测按键 K1 是否按下
        {
                delay(1000); //消除抖动 一般大约 10ms
                if(k2==0) //再次判断按键是否按下
                {
                        j++; //led 状态取反
                        LcdWriteCom(0x01);
                }
                while(!k2); //检测按键是否松开
               
        }

}
void keyprosC()
{
        if(k3==0) //检测按键 K1 是否按下
        {
                delay(1000); //消除抖动 一般大约 10ms
                if(k3==0) //再次判断按键是否按下
                {
                        k++; //led 状态取反
                        LcdWriteCom(0x01);
                }
                while(!k3); //检测按键是否松开
               
        }

}
/*********************************************************************************************
函数名:主函数


结  果:读DHT11数据并送到1602显示**********************************************************************************************/
void main (void)
{
        static uint n;
        Timer0Init();
        LcdInit();
        Delay1s();                //LCD初始化
        while(1)
        {
                keyprosA();
                keyprosB();
                keyprosC();


                if(TF0==1)          //定时器T0溢出标志
                {
                        TF0=0;
                        TH0=0Xd8;        //给定时器赋初值,定时10ms
                        TL0=0Xf0;
                        n++;
                }
                if(n==100)
                {
                        n=0;
                        miao++;
                        if(miao==60)
                        {
                                miao=0;
                                fen++;
                                if(fen==60)
                                {
                                        fen=0;
                                        shi++;
                                        if(shi==60)
                                        {
                                                shi=0;
                                                miao=0;
                                                fen=0;
                                        }
                                }
                        }
                        if(i%5==0)        
                        {
                                
                                DHT11_receive();//接受数据
                                if(RH>hrh||RH<lrh||TH>hth||TH<lth)
                                {
                                        led=~led;
                                }
                                else
                                {
                                        led=1;
                                }
                                LcdWriteCom(0x80);//uchar Disp[]="RTHC%·";
                                LcdWriteData(Disp[0]);//R
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(dat_r[0]);
                        LcdWriteData(dat_r[1]);
                                LcdWriteData(Disp[4]);
                                LcdWriteCom(0x08+0x80);
                                LcdWriteData(Disp[1]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(dat_r[2]);
                        LcdWriteData(dat_r[3]);
                                LcdWriteData(Disp[3]);
                                timepros();
                                LcdWriteCom(0x44+0x80);
                                LcdWriteData(b[0]);
                        LcdWriteData(b[1]);
                                LcdWriteData(0X3a);
                                LcdWriteData(b[3]);
                        LcdWriteData(b[4]);
                                LcdWriteData(0X3a);
                                LcdWriteData(b[6]);
                        LcdWriteData(b[7]);
                        }
                        else if(i%5==1)
                        {
                                if(j!=0)
                                {
                                        lrh=lrh+j;
                                        j=0;
                                }
                                if(k!=0)
                                {
                                        lrh=lrh-k;
                                        k=0;
                                }
                                secondtimepros();
                                //首行
                                LcdWriteCom(0x80);//uchar Disp[]="RTHC%·";
                                LcdWriteData(Disp[0]);//R
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[0]);
                        LcdWriteData(c[1]);
                                LcdWriteData(Disp[4]);
                                LcdWriteData(0X2a);//<
                                LcdWriteCom(0x08+0x80);
                                LcdWriteData(Disp[0]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[2]);
                        LcdWriteData(c[3]);
                                LcdWriteData(Disp[4]);
                                
                                
                                LcdWriteCom(0x40+0x80);
                                LcdWriteData(Disp[1]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[4]);
                        LcdWriteData(c[5]);
                                LcdWriteData(Disp[3]);
                                LcdWriteCom(0x48+0x80);
                                LcdWriteData(Disp[1]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[6]);
                        LcdWriteData(c[7]);
                                LcdWriteData(Disp[3]);        
                        }
                        else if(i%5==2)
                        {
                                if(j!=0)
                                {
                                        hrh=hrh+j;
                                        j=0;
                                }
                                if(k!=0)
                                {
                                        hrh=hrh-k;
                                        k=0;
                                }
                                secondtimepros();
                                //首行
                                LcdWriteCom(0x80);//uchar Disp[]="RTHC%·";
                                LcdWriteData(Disp[0]);//R
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[0]);
                        LcdWriteData(c[1]);
                                LcdWriteData(Disp[4]);
                                LcdWriteCom(0x08+0x80);
                                LcdWriteData(Disp[0]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[2]);
                        LcdWriteData(c[3]);
                                LcdWriteData(Disp[4]);
                                LcdWriteData(0X2a);//<
                                
                                LcdWriteCom(0x40+0x80);
                                LcdWriteData(Disp[1]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[4]);
                        LcdWriteData(c[5]);
                                LcdWriteData(Disp[3]);
                                LcdWriteCom(0x48+0x80);
                                LcdWriteData(Disp[1]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X2a);//:
                                LcdWriteData(c[6]);
                        LcdWriteData(c[7]);
                                LcdWriteData(Disp[3]);        
                        }
                        else if(i%5==3)
                        {
                                if(j!=0)
                                {
                                        lth=lth+j;
                                        j=0;
                                }
                                if(k!=0)
                                {
                                        lth=lth-k;
                                        k=0;
                                }
                                secondtimepros();
                                //首行
                                LcdWriteCom(0x80);//uchar Disp[]="RTHC%·";
                                LcdWriteData(Disp[0]);//R
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[0]);
                        LcdWriteData(c[1]);
                                LcdWriteData(Disp[4]);
                                LcdWriteCom(0x08+0x80);
                                LcdWriteData(Disp[0]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[2]);
                        LcdWriteData(c[3]);
                                LcdWriteData(Disp[4]);
                                
                                
                                LcdWriteCom(0x40+0x80);
                                LcdWriteData(Disp[1]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[4]);
                        LcdWriteData(c[5]);
                                LcdWriteData(Disp[3]);
                                LcdWriteData(0X2a);//<
                                LcdWriteCom(0x48+0x80);
                                LcdWriteData(Disp[1]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[6]);
                        LcdWriteData(c[7]);
                                LcdWriteData(Disp[3]);        
                        }
                        else if(i%5==4)
                        {
                                if(j!=0)
                                {
                                        hth=hth+j;
                                        j=0;
                                }
                                if(k!=0)
                                {
                                        hth=hth-k;
                                        k=0;
                                }
                                secondtimepros();
                                //首行
                                LcdWriteCom(0x80);//uchar Disp[]="RTHC%·";
                                LcdWriteData(Disp[0]);//R
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[0]);
                        LcdWriteData(c[1]);
                                LcdWriteData(Disp[4]);
                                LcdWriteCom(0x08+0x80);
                                LcdWriteData(Disp[0]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[2]);
                        LcdWriteData(c[3]);
                                LcdWriteData(Disp[4]);
                                
                                
                                LcdWriteCom(0x40+0x80);
                                LcdWriteData(Disp[1]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[4]);
                        LcdWriteData(c[5]);
                                LcdWriteData(Disp[3]);
                                LcdWriteCom(0x48+0x80);
                                LcdWriteData(Disp[1]);//T
                                LcdWriteData(Disp[2]);//H
                                LcdWriteData(0X3a);//:
                                LcdWriteData(c[6]);
                        LcdWriteData(c[7]);
                                LcdWriteData(Disp[3]);
                                LcdWriteData(0X2a);//<        
                        }
                        
                }
        }
}

视频.gif (4.26 MB, 下载次数: 69)

成果图

成果图

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:372579 发表于 2022-2-25 07:38 来自手机 | 只看该作者
感觉那程序好复杂
回复

使用道具 举报

板凳
ID:863362 发表于 2022-2-25 11:28 | 只看该作者
main.c和lcd1602.c里调用的是lcd1602.h不是led1602.h
回复

使用道具 举报

地板
ID:988780 发表于 2022-2-25 11:53 | 只看该作者
代码运行,需要将lcd1602.h文件名改为led1602.h,或者在main.c和lcd1602.c中将调用led1602.h改为lcd1602.c
回复

使用道具 举报

5#
ID:1018456 发表于 2022-11-16 20:30 | 只看该作者
楼主为什么仿真上面有温湿度显示出来????
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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