找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于8155的温度控制器

[复制链接]
跳转到指定楼层
楼主
ID:539641 发表于 2019-5-16 10:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/******************************************基于8155的8LED显示温度控制器设计***************************/

#include<reg52.h>
#include<absacc.h>

/*******************************************宏定义***************************************************/

#define uint unsigned int
#define uchar unsigned char

/*******************************************定义8155地址***********************************************/

#define COM8155  XBYTE[0X7FF8]                  //8155的命令口
#define PA8155   XBYTE[0X7FF9]                  //8155的PA
#define PB8155   XBYTE[0X7FFA]                  //8155的PB
#define PC8155   XBYTE[0X7FFB]                  //8155的PC

/*********************************************定义DS18B20引脚**********************************************/

sbit DS18B20=P3^0;                           //DDS18B20引脚

/*********************************************定义蜂鸣器引脚**********************************************/
sbit lamp=P1^5;

/*******************************************定义数码管显示的码值**************************************/

uchar code du_code[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7c,0x39,0x5e,0x79,0x71};         //数码管显示0~F的码值          
uchar  dis_buf[]={0x3f,0x3f,0x40,0x3f,0x3f,0x40,0x3f,0x3f};                            //数码管显示缓存,格式为MM-NN-SS;8155内部的RAM开始的地址是0x3f00
uchar code bit_code[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};                   //数码管显示的位值

/*********************************************定义系统变量***************************************************/

uchar hour,minute,second;                                          //定义时间变量
//uchar hour3=0,minute3=0,second3=0;//定义总时间的时间变量
//char hour1=0,minute1=0,second1=5;                          //定义采样间隔变量 ; 一开始小时数为0,分钟数为0,秒数为5
char hour2=0,minute2=0,second2=5;                          //定义采样总时间变量 ; 一开始小时数为0,分钟数为0,秒数为5
char highest=99,lowest=0;         //装设定的最大值和最小值
uchar count,count1,num,count2;                                                  //定义计数器变量
uint count3=0;
uchar str[8];                                                                  //定义数显示温度
uchar temp=0;                                                                  //定义显示温度平均值变量
uchar temp1[2];                                                                 //        定义数组存储温度值
bit flag=0;                                                                         //        定义时间标志位
bit flag1,flag2,flag3,flag4,flag5;                        //定义按键标志位
uint st=0x3f00;                                                                 //定义8155RAM起始地址

uint x=0x3f00;//存温度时指向内存
uchar q=0; //标注是否按下5键,是否开始计数

/*********************************************延时程序***************************************************/
//us延时程序
void delayus(uint x)                       
{
        while(x--);
}
//ms延时程序
void delayms(uint x)                          
{
        uchar y;
        for(;x>0;x--)
                for(y=110;y>0;y--)
                        ;
}
/*********************************************DS18B20程序***************************************************/
//18b20初始化程序
void Init_DS18B20(void)                   
{
         uchar x=0;
         DS18B20 = 1;                           //DS18B20复位
         delayus(8);                          //稍做延时
         DS18B20 = 0;                             //单片机将DS18B20拉低
         delayus(80);                           //精确延时 大于 480us
         DS18B20 = 1;                               //拉高总线
         delayus(10);
         x=DS18B20;                                  //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
         delayus(5);
}

//读一个字节
unsigned char ReadOneChar(void)             
{
        uchar i=0;
        uchar dat = 0;
        for (i=8;i>0;i--)
         {
          DS18B20 = 0;                                 // 给脉冲信号
          dat>>=1;
          DS18B20 = 1;                               // 给脉冲信号
          if(DS18B20)
           dat|=0x80;
          delayus(5);                                                                  //延时
         }
         return(dat);
}

//写一个字节
void WriteOneChar(uchar dat)
{
         uchar i=0;
         for (i=8; i>0; i--)
         {
                  DS18B20 = 0;
                  DS18B20 = dat&0x01;
                  delayus(5);
                  DS18B20 = 1;
                  dat>>=1;
         }
        delayus(5);
}

//读温度值
uchar ReadTemperature(void)         //读取温度
{
        unsigned char a=0;
        unsigned char b=0;
        unsigned char t=0;
        Init_DS18B20();
        WriteOneChar(0xCC); // 跳过读序号列号的操作
        WriteOneChar(0x44); // 启动温度转换
        delayus(200);
        Init_DS18B20();
        WriteOneChar(0xCC); //跳过读序号列号的操作
        WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
        a=ReadOneChar();
        b=ReadOneChar();
       
        b<<=4;
        b+=(a&0xf0)>>4;
        t=b;
        return(t);                                                          //返回温度值
}

/*********************************************扫描键盘程序***************************************************/
void keyscan()
{
         uchar m;
         m=PC8155;
         m=m&0x1f;
         if(m!=0x1f)//有按键被按下
         {
                  delayms(10);                                                           //延时消抖
                  PB8155=0x0f;
                  m=PC8155;
                  m&=0x1f;
                  if(m!=0x1f)                //消抖后仍有按键被按下               
                  {
                           m=PC8155;
                           m&=0x1f;
                           switch(m)
                           {
                                    case(0x1e):flag1=1;break;                  // flag1为1, 按键1被按下
                                    case(0x1d):flag2=1;break;                  //按键2被按下,flag2为1
                                    case(0x1b):flag3=1;break;                  //按键3被按下,flag3为1
                                    case(0x17):flag4=1;break;                  //按键4被按下,flag4为1
                                        case(0x0f):flag5=1;break;//按键5
                           }
                   }
                   while(PC8155!=0x1f);                                                //等待按键松开,松开以后执行下面的程序
                 }

                if(flag5==1)
                {
                 q = !q;
                 x=0x3f00;
                 st=0x3f00;
                 flag5=0;
                 }

                if(flag1==1)                       
                {
                        count++;
                        count2=0;
                        if(count>=4)                                         //按键1被按下,功能计数器加1,跳转到下一个功能
                                count=0;
                        flag1=0;                               
                }
                if(count==1)                                           //判断当前是否在功能1状态下
                {                       
                         
                        if(flag2==1)                                  
                        {
                               
                                 count2++;                                        //按键2被按下,采样时间小时加1
                                 if(count2>=3)                                   //判断时间界限
                                         count2=0;
                                 flag2=0;                                               
                        }
       
                        if(flag3==1)                          
                        {         
                                if(count2==0)lowest++        ; if(lowest < 0)        lowest=0;
                                if(count2==2)highest++        ; if(highest > 99)  highest=99;
                                flag3=0;                                  
                        }
       
                        if(flag4==1)                               
                        {
                                 if(count2==0)         lowest--; if(lowest<0)        lowest=0;
                                if(count2==2)         highest--; if(highest>99)highest=99;
                                flag4=0;                                 
                         }
                }
                if(count==2)
                {                                                                         //判断当前是否在功能2状态下
                  
                        if(flag2==1)
                        {
                                if(st<0x3fff)
                                        st++;                                         //判断RAM地址范围
                                flag2=0;                                         //RAM地址加1
                        }
                        if(flag3==1)
                        {
                                if(st>0x3f00)                                 //判断RAM地址范围
                                        st--;                                         //RAM地址减1
                                flag3=0;
                        }
                }
                if (count==3)
                {
                  if(flag2==1)                                  
                        {
                               
                                 count2++;                                        //按键2被按下,采样时间小时加1
                                 if(count2>=3)                                   //判断时间界限
                                         count2=0;
                                 flag2=0;                                               
                        }
       
                        if(flag3==1)                          
                        {         
                                if(count2==0)        second2++; if(second2==60)        second2=0;
                                if(count2==1)        minute2++; if(minute2==60)        minute2=0;
                                if(count2==2)        hour2++;   if(hour2==24)        hour2=0;
                                flag3=0;                                  
                        }
       
                        if(flag4==1)                               
                        {
                                 if(count2==0)          second2--; if(second2<0)        second2=59;
                                if(count2==1)          minute2--; if(minute2<0)        minute2=59;
                                if(count2==2)          hour2--;   if(hour2<0)        hour2=23;
                                flag4=0;                                 
                         }        
                }
}
/*********************************************初始化程序***************************************************/
void initial()
{
        COM8155=0x03;                                                         //初始化8155
        TMOD=0x11;                                                                 //定时器工作方式初始化,设置T1,T2定时器的工作模式
        TH0=(65536-1000)/256;
        TL0=(65536-1000)%256;                                         //定时器0装初值
        TH1=(65536-50000)/256;                                         
        TL1=(65536-50000)%256;                                          //定时器1装初值
        ET0=1;                                                                          //开定时器0中断
        ET1=1;                                                                         //开定时器1中断
        EA=1;                                                                          //开总中断
        TR0=1;                                                                          //开定时器0
        TR1=1;                                                                          //开定时器1
}


/*********************************************主程序***************************************************/
void main()
{
    uint sumtime;
    uint o=0;
        uchar ss;
        uchar j=0x00;
        initial();                                                //系统初始化,即8051初始化
        for(;x<=0x3fff;x++)
                XBYTE[x]=0x00;                                //RAM初始化,8155内部有256字节的RAM
        x=0x3f00;
    st=0x3f00;
                        while(1)
                {

                     keyscan();                                        //键盘扫描
                         sumtime=(60*minute2+second2+0x3f00);
                    if(flag==1)
                 {
                            temp=ReadTemperature();                //读温度值
                            second=0;
                                minute=0;
                                hour=0;                                                                                          //时间值清零
                    flag=0;       
                           if(q==1)
                        {
                if(x<sumtime)
                            {
                                      XBYTE[x++]=temp/10*16+temp%10;                                           //装储存的温度值
                             }
                        }
                        if(temp < highest && temp > lowest)
                          {
                             lamp=0;
                                 if(count==0)
                                     {
                                                str[0]=0;
                                                str[1]=0;
                                                  str[2]=du_code[temp/10];   //取除到的数相对应的数码管显示的码组存放在str数组中
                                                   str[3]=du_code[temp%10];
                                                str[4]=0x63;
                                                str[5]=0x39;
                                                str[6]=0;
                                                 str[7]=0;                                         //装温度值

                                       }
       
                             }
                        else
                           {
                                for(o=10;o>0;o--)
                                      {
                                          lamp=0;
                                  lamp=~lamp;
                                              delayms(0.3);
                                       }
                  
                                    str[0]= 0;
                                        str[1]=0;
                                           str[2]=du_code[14];
                                           str[3]=du_code[14];            //显示“EEEE”表示错误
                                           str[4]=du_code[14];
                                          str[5]=du_code[14];
                                        str[6]=0;
                                        str[7]=0;

                               }
                }
                if(count==1)
                {
                        dis_buf[0]=du_code[highest/10];
                        dis_buf[1]=du_code[highest%10];
                        dis_buf[3]=0x40;
                        dis_buf[4]=0x40;
                        dis_buf[6]=du_code[lowest/10];
                        dis_buf[7]=du_code[lowest%10];                   //装门限时间值
                }

                if(count==2)
                {
                    ss=XBYTE[st];
                        str[0]=du_code[ss/16];
                        str[1]=du_code[ss%16];
                        str[2]=0x63;
                        str[3]=0x39;
                        str[4]=0x40;
                        str[5]=0x40;
                        str[6]=du_code[(st-0x3f00)/10];
                        str[7]=du_code[(st-0x3f00)%10];                                                   //装储存的温度值
                }
                if(count==3)
                {
            dis_buf[0]=du_code[hour2/10];
                        dis_buf[1]=du_code[hour2%10];
                        dis_buf[3]=du_code[minute2/10];
                        dis_buf[4]=du_code[minute2%10];
                        dis_buf[6]=du_code[second2/10];
                        dis_buf[7]=du_code[second2%10];                   //装采样总时间值

                }
          
                  
}
}
//}

/*********************************************定时器0中断程序***************************************************/
void timer0() interrupt 1
{

                                                          //装初值       
        if(count==0)
        {
                TH0=(65536-4000)/256;
                TL0=(65536-4000)%256;
                PB8155=bit_code[count1];                                                //送数码管的位值
                PA8155=str[count1];                                                        //显示温度值
        }

        if(count==2)
        {
                TH0=(65536-4000)/256;
                TL0=(65536-4000)%256;
                PB8155=bit_code[count1];                                                //送数码管的位值
                PA8155=str[count1];                                                        //显示温度值
               
        }
        if(count==1||count==3)
        {
                TH0=(65536-500)/256;
                TL0=(65536-500)%256;
                count3++;
                if(count3<=600)
                {
                        PB8155=bit_code[count1];
                        PA8155=dis_buf[count1];                                                //显示采样时间间隔
                }
                else
                {
                        if(count2==0)
                        {

                                 if(count1==6||count1==7)
                                        PB8155=0xff;
                                else
                                        PB8155=bit_code[count1];                           //秒闪烁
                                PA8155=dis_buf[count1];       
                        }
                        if(count2==1)
                        {
                                 if(count1==3||count1==4)
                                        PB8155=0xff;
                                else
                                        PB8155=bit_code[count1];
                                PA8155=dis_buf[count1];                                          //分钟闪烁
                        }
                        if(count2==2)
                        {
                                if(count1==0||count1==1)
                                        PB8155=0xff;
                                else
                                        PB8155=bit_code[count1];
                                PA8155=dis_buf[count1];                                        //小时闪烁
                        }
                        if(count3>1200)
                                count3=0;
                }
        }

       
               
       
        count1++;
        if(count1>=8)
                count1=0;       
}

/*********************************************定时器1中断程序***************************************************/
void timer1() interrupt 3
{
        TH1=(65536-50000)/256;
        TL1=(65536-50000)%256;                                                 //装初值
        num++;
        if(num==20)
        {
                num=0;
                flag=1;
                second++;                                                         //1秒时间到
                if(second==60)
                {
                        second=0;
                        minute++;                                                         //1分钟时间到
                        if(minute==60)
                        {
                                minute=0;
                                hour++;                                                        //1小时时间到
                                if(hour==24)
                                        hour=0;      
                        }
                }
    }
}
       

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

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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