找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机温湿度传感器检测系统程序设计

[复制链接]
跳转到指定楼层
楼主
ID:677549 发表于 2019-12-30 15:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
技术路线及预期目标:
技术路线:本设计是基于AT89C51为核心的单片机温度监控系统。温度信号由DHT11温度传感器进行采集,输入单片机,由单片机对数字信号进行相应的处理,最终在1602显示模块上显示。
预期目标:本系统以教室为一个温度湿度采集范围。
1.被测温度均可以在显示模块上以数字形式显示。
2.被测温度范围为     ℃,湿度范围     精度为±0.5℃。
3.温度和湿度超过额定值时,产生声光报警。
   
   

主要内容:
1、温度监控系统硬件结构设计
①掌握温度采集模块DHT11的工作原理和工作方式。
②掌握AT89C51芯片和显示模块1602的工作原理。
③系统对达到报警条件的温度,如果达到报警让LED灯产生变化。
2、硬件电路主要分为单片机系统、显示电路、报警电路、温度模块采集电路等。单片机系统通过温度采集模块采集温度,发送到基于AT89C51的单片机,通过基于AT89C51的单片机处理后,将结果送至显示模块显示,并判断温度是否达到报警条件。
3、温度监控系统软件设计:通过Keil uVision4编写本次设计的程序代码,对代码进行调试,完成后使用烧写软件STC_ISP_V480将程序烧写进单片机。
4、绘制系统总体结构图,系统原理图,软件流程图。
5、对该系统可能存在的技术和理论问题,作必要的分析和探索研究。

    /********************************************************************************/
    #include <reg52.h>
    #include <intrins.h>
    #define uchar unsigned char //宏定义
    #define uint unsigned int
    typedef unsigned char unint8;
    typedef unsigned char unint16;
    typedef unsigned int U16;
    uchar code table[] = {" s: %RH "};
    uchar code table1[] ={" w: "};
    uchar code table2[] ={"SH: % WH: C "};
    uchar code table3[] ={"SL: % WL: C "};
    sbit TRH = P1^1;//温湿度传感器DHT11数据接入
    sbit rs = P2^6;
    sbit en = P2^7;
    sbit beep=P1^0;//蜂鸣器控制端
    sbit k1=P3^1;
    sbit k2=P3^2;
    sbit k3=P3^3;
    uchar htemp=33,ltemp=15,hrh=60,lrh=10; //温湿度上下线初始化
    bit yyp=1,lalarm=0; //设置标志位,报警标志位
    uchar s1num,num,shis,shig,wens,weng;
    unint8 TH_data,TL_data,RH_data,RL_data,CK_data; // dht11内部变量定义
    unint8 TH_temp,TL_temp,RH_temp,RL_temp,CK_temp; // dht11内部变量定义
    unint8 com_data,untemp,temp;
    unint8 respond;
    void delay(uint x) //毫秒级延时函数
    {
    uint i,j;
    for(i=x;i>0;i--)
    for(j=110;j>0;j--);
    }
    void di() //蜂鸣器报警
    {
    beep=0;
    delay(100);
    beep=1;
    }
    void write_com(uchar com)
    {
    rs=0;//命令
    P0=com;
    delay(5);
    en=1;
    delay(5);
    en=0;
    }
    void write_date(uchar date)
    {
    rs=1;//数据
    P0=date;
    delay(5);
    en=1;
    delay(5);
    en=0;
    }
    void init1602()
    {
    write_com(0x38); //设置工作方式
    write_com(0x0c); //设置光标
    write_com(0x06); //设置输入方式
    write_com(0x01); //清屏
    write_com(0x80);
    for(num=0;num<16;num++)
    {
    write_date(table[num]);
    }
    write_com(0x80+0x40);
    for(num=0;num<16;num++)
    {
    write_date(table1[num]);
    }
    }
    void init16021() //设置温度上下限显示初始化函数
    {
    write_com(0x80);
    for(num=0;num<16;num++)
    {
    write_date(table2[num]);
    }
    write_com(0x80+0x40);
    for(num=0;num<16;num++)
    {
    write_date(table3[num]);
    }
    write_com(0x80+0x40+13);
    write_date(0xdf);
    write_com(0x80+13);
    write_date(0xdf);

    }
    void write_H(uchar add,uchar date)
    {
    uchar shi,ge;
    shi=date/10;
    ge=date%10;
    write_com(0x80+add);
    write_date(0x30+shi);
    write_date(0x30+ge);
    }

    void write_L(uchar add,uchar date)
    {
    uchar shi,ge;
    shi=date/10;
    ge=date%10;
    write_com(0x80+0x40+add);
    write_date(0x30+shi);
    write_date(0x30+ge);
    }
    /////////////////////////////////
    /***********DHT11子程序*************************/
    /*********************************************************************************/

    /*********************************************************************************/
    // 毫秒级延时子程序
    /*********************************************************************************/
    void delay_ms(U16 j)
    { unint8 i;
    for(;j>0;j--)
    {
    for(i=0;i<27;i++);

    }
    }
    /*********************************************************************************/

    /*********************************************************************************/
    //5us级延时程序
    /*********************************************************************************/
    void delay_us()
    {
    unint8 i;
    i--;
    i--;
    i--;
    i--;
    i--;
    i--;
    }
    /********************************************************************************/

    /****************************************************************************/
    //收发信号检测,数据读取
    /****************************************************************************/
    char receive()
    {
    unint8 i;
    for(i=0;i<8;i++)
    {
    respond=2;
    while((!TRH)&&respond++);
    delay_us();
    delay_us();
    delay_us();

    temp=0;


    if(TRH)temp=1;
    respond=2;
    while((TRH)&&respond++);
    //超时则跳出for循环
    if(respond==1)break;

    //判断数据位是0还是1

    // 如果高电平高过预定0高电平值则数据位为 1
    com_data<<=1;
    com_data|=temp;
    }
    return(com_data);
    }
    /****************************************************************************/

    /****************************************************************************/
    //湿度读取子程序
    //温度高8位== TL_data
    //温度低8位== TH_data
    //湿度高8位== RH_data
    //湿度低8位== RH_data
    //校验 8位 == CK_data
    //调用的程序有 delay();, Delay_5us();,RECEIVE();
    /***************************************************************************/
    void GET_TRH()
    {
    //主机拉低18ms
    TRH=0;
    delay_ms(180);
    TRH=1;
    //DATA总线由上拉电阻拉高 主机延时20us
    delay_us();
    delay_us();
    delay_us();
    delay_us();
    //主机设为输入 判断从机响应信号
    TRH=1;
    //判断DHT11是否有低电平响应信号 如不响应则跳出,响应则向下运行
    if(!TRH)
    {
    respond=2;
    //判断DHT11发出 80us 的低电平响应信号是否结束
    while((!TRH)&& respond++);
    respond=2;
    //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
    while(TRH && respond++);
    //数据接收状态
    RH_temp = receive();
    RL_temp = receive();
    TH_temp = receive();
    TL_temp = receive();
    CK_temp = receive();
    TRH=1;//ST=1;
    //数据校验
    untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
    if(untemp==CK_temp)
    {
    RH_data = RH_temp;
    RL_data = RL_temp;
    TH_data = TH_temp;
    TL_data = TL_temp;
    CK_data = CK_temp;
    }
    }
    //湿度整数部分
    shis= (char)(0X30+RH_data/10); //湿度的十位
    shig= (char)(0X30+RH_data%10); //湿度的个
    //温度整数部分
    wens= (char)(0X30+TH_data/10); //温度的十位
    weng= (char)(0X30+TH_data%10); //温度的个位
    //温湿度显示函数
    write_com(0x80+6);
    write_date(shis);
    write_date(shig);
    write_date('%'); //湿度符号
    write_com(0x80+0x40+6);
    write_date(wens);
    write_date(weng);
    write_date(0xdf); //温度符号
    write_date('C');


    }

    /****按键扫描******/
    void keyscan()
    {
    if(k1==0)
    {
    delay(10);
    if(k1==0)
    {
    s1num++;
    while(!k1); //等待按键释放
    yyp=0;
    di();
    switch(s1num)
    {
    case 1: init16021(); //设置温度上下限初始化
    write_H(3,hrh);
    write_H(11,htemp);
    write_L(3,lrh);
    write_L(11,ltemp);
    write_com(0x80+4);
    write_com(0x0f); //打开光标
    break;
    case 2: write_com(0x80+0x40+4);
    break;
    case 3: write_com(0x80+12);
    break;
    case 4: write_com(0x80+0x40+12);
    break;
    case 5: s1num=0;
    write_com(0x0c); //关闭光标
    yyp=1;
    init1602(); //上电后显示初始化
    break;
    }
    }
    }
    if(s1num!=0)
    {
    if(k2==0)
    {
    delay(10);
    if(k2==0)
    {
    while(!k2); //等待按键释放
    di();
    switch(s1num)
    {
    case 1: hrh++;
    if(hrh==85)hrh=0;
    write_H(3,hrh);
    write_com(0x80+4);

    break;
    case 2: lrh++;
    if(lrh==60)lrh=0;
    write_L(3,lrh);
    write_com(0x80+0x40+4);

    break;
    case 3: htemp++;
    if(ltemp==50)ltemp=0;
    write_H(11,htemp);
    write_com(0x80+11);

    break;
    case 4: ltemp++;
    if(ltemp==50)ltemp=0;
    write_L(11,ltemp);
    write_com(0x80+0x40+12);

    break;
    }
    }
    }
    if(k3==0)
    {
    delay(10);
    if(k3==0)
    {
    while(!k3); //等待按键释放
    di();
    switch(s1num)
    {
    case 1: hrh--;
    if(hrh==0)hrh=85;
    write_H(3,hrh);
    write_com(0x80+4);

    break;
    case 2: lrh--;
    if(lrh==0)lrh=60;
    write_L(3,lrh);
    write_com(0x80+0x40+4);

    break;
    case 3: htemp--;
    if(ltemp==0)ltemp=50;
    write_H(11,htemp);
    write_com(0x80+11);

    break;
    case 4: ltemp--;
    if(ltemp==0)ltemp=50;
    write_L(11,ltemp);
    write_com(0x80+0x40+12);

    break;
    }
    }
    }
    }
    }
    void baojing()
    {
    if((TH_data>htemp||RH_data>hrh)||(TH_data<ltemp||RH_data<lrh))//判断温湿度
    {
    lalarm=1;
    if(RH_data>hrh||RH_data<lrh) // 报警
    {

    }
    else
    {

    }
    }
    else //不报警
    {
    lalarm=0;
    if(yyp==1)
    {

    }
    }
    if(lalarm==1)
    {
    di();
    delay(100);
    di();
    delay(100);
    }
    }
    /****************************************************************************/
    //主函数
    //TH,TL,RH,RL分别代表温湿度的整数和小数部分
    /****************************************************************************/
    void main()
    {
    init1602();

    while(1)
    {
    keyscan();
    if(yyp==1)
    {
    keyscan();
    GET_TRH();
    baojing();

    }
    }
    }




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

使用道具 举报

沙发
ID:686752 发表于 2020-3-6 18:07 | 只看该作者
请问有这个程序的电路图吗
回复

使用道具 举报

板凳
ID:276936 发表于 2020-3-15 15:38 | 只看该作者
我也想要,有吗?
回复

使用道具 举报

地板
ID:473504 发表于 2020-3-24 16:50 | 只看该作者
这文本编辑有点差吧,变量那么多也不注释一下,读者看起来很麻烦的。而且后面的报警函数内容缺失。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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