找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于单片机的恒温控制

[复制链接]
跳转到指定楼层
楼主
ID:530536 发表于 2019-5-15 14:52 来自手机 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg52.h>
#include"mytype.h"
#include"led.h"
#include"ds18b20.h"
#include"key.h"


/*****继电器端口***********/
sbit cold=P1^4;
sbit heat=P1^5;

sbit buzzer=P1^6;  //蜂鸣器

uint  tvalue;

uint dig3,dig2,dig1,dig0;          //digx数码管要显示的数据,在led.h中声明的外部变量
uint dig3_u,dig2_u,dig1_u,dig0_u; //保存设置上限  up
uint dig3_d,dig2_d,dig1_d,dig0_d; //保存设置下限  down

uchar key;                                          //key是key的返回值,在key.h中声明的外部变量

uchar kflag,kshift=1,kmode=0;//按键设置标志、闪烁led的移位按键、按键模式(上下限温度)
uint  temp;                //缓存温度

void KeyCtrl();//按键控制

void main(void)
{

        TMOD=0x01; //方式1的定时计数50ms,设置定时器每一段时间采集温度值
          TH0=0x3c;         
          TL0=0xb0;
        EA=1;
        TR0=1;
        ET0=1;
       
        dig2_u=5;  //初始化上限50.0度
        dig1_u=0;
        dig0_u=0;

        dig2_d=3;  //初始化下限30.0度
        dig1_d=0;
        dig0_d=0;

        while(1)
        {                               
                if(KeyScan())KeyCtrl();//扫描到按键执行按键控制,否则跳过

                if(kflag) //如果按键设置标志为1,进入闪烁显示
                {                       
                        LedFlick(kshift); //数码管闪烁显示
                }
                else
                {
                        temp=tvalue;  //tvalue是外部变量,在定时器执行中断采集温度时ReadTemp();改变温度值
                        dig3=0;
                        dig2=temp/100%10;   
                        dig1=temp/10%10 ;   
                        dig0=temp%10;

                        LedScan();//数码管显示采集温度

                                if( temp>(dig2_u*100+dig1_u*10+dig0_u) )//大于上限值报警并制冷
                                {       
                                        buzzer=1;
                                        heat=0;       
                                        cold=1;
                                }
                                else if(temp<(dig2_d*100+dig1_d*10+dig0_d) )//小于下限值报警并制热
                                {
                                        buzzer=1;
                                        heat=1;
                                        cold=0;
                                }
                                else //不报警停止制冷制热
                                {
                                        buzzer=0;
                                        heat=0;        //高电平有效,此处关闭制热
                                        cold=0;        //高电平有效,此处关闭制冷
                                }                               
                }
                                       
        }       
               
}
/***********按键控制函数,模式、加减、确认***********/
void KeyCtrl()
{

        if(key)        //key是外部变量,在扫描的时候改变,在退出这个函数前清零,否则会一直保持控制,闪啊闪的
        {
                switch(key)        //判断扫描到的按键是什么,作出相应的操作
                {
                        case 1: kflag=1;         //模式切换按键
                                    kmode++;
                                        if(kmode==1)//把保存的上限温度值显示出来
                                        {
                                                dig0=dig0_u;
                                                dig1=dig1_u;
                                                dig2=dig2_u;
                                                dig3=11;//'H'                                               
                                        }
                                        else if(kmode==2) //把保存的下限温度值显示出来
                                        {
                                                dig0=dig0_d;
                                                dig1=dig1_d;
                                                dig2=dig2_d;
                                                dig3=12;//'L'                                       
                                        }
                                        else if(kmode==3) //恢复温度采集显示
                                        {
                                                kmode=0;
                                                kflag=0;
                                                dig3=0;
                                        }
                                        break;
                        case 2: kshift++;         //闪烁位左移按键
                                        if(kshift==4)kshift=1;
                                        break;

                        case 3:        if(kflag)   //加1按键
                                        switch(kshift)
                                        {
                                                case 1: dig0++;
                                                                if(dig0==10)dig0=0;        //之所以这样,是避免dig0加到10以上会显示数组段码的后面的字符
                                                                break;
                                                case 2: dig1++;
                                                                if(dig1==10)dig1=0;
                                                                break;
                                                case 3: dig2++;
                                                                if(dig2==10)dig2=0;
                                                                break;
                                        }
                                        break;
                        case 4:        if(kflag)         //减1按键
                                        switch(kshift)
                                        {
                                                case 1: dig0--;
                                                                if(dig0==-1)dig0=9;
                                                                break;
                                                case 2: dig1--;
                                                                if(dig1==-1)dig1=9;
                                                                break;
                                                case 3: dig2--;
                                                                if(dig2==-1)dig2=9;
                                                                break;
                                        }
                                        break;
                        default:break;
                }
        }
        if(kmode==1)  //把显示的温度值上限保存一下
        {
                dig0_u=dig0;
                dig1_u=dig1;
                dig2_u=dig2;
                dig3_u=dig3;                                               
        }
        else if(kmode==2) //把显示的温度值下限保存一下
        {
                dig0_d=dig0;
                dig1_d=dig1;
                dig2_d=dig2;
                dig3_d=dig3;                                       
       
        }
        key=0;                                               
}

/**********定时中断每隔一段时间采集一次当前温度******/
void time0() interrupt 1
{
        uchar cnt;
        TH0=0x3c; //重赋初值
        TL0=0xb0;
               
        if(!cnt)
        {
                ReadTemp();
        }
        cnt++;
        if(cnt==4)cnt=0; //50ms*4=1/5s采集一次温度值
}

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

使用道具 举报

沙发
ID:1 发表于 2019-5-15 21:55 | 只看该作者
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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