8051单片机各种问题 跪求高人指教

2020-02-02 09:34发布

IOP3.1低电平就执行if后语句,让他显示上限温度值,怎么一按按键,4位数码管就不显示了

我用proteus也仿真出来了。。电路我觉得没问题,也检查了好几遍。我做的是温度传感器,功能是显示温度 通过三个按键来控制温度上下限值,然后检测 如果超出则报警。。它能够显示温度,但是不能够通过按键和中断来调整上下限温度值。。请高手指教。我是学生,菜鸟,也没有财富值。。但请您看在我是学生的份上就帮帮我吧,好人一定好报。。急!!!!送上电路图 和仿真图 还有程序代码。。

#include<reg52.h>
#include<intrins.h>

#define uint unsigned int
#define uchar unsigned char


bit f_biao ;   //当显示上下限温度时的闪烁间隔
sbit DQ=P3^7;        //ds18b20数据端
sbit SET=P3^1;         //显示上下限温度
sbit DEC=P3^2;          //调整上下限温度,使上下限温度减少
sbit ADD=P3^3 ;          //使上下限温度增加
sbit BEEP=P1^4;          //蜂鸣器
sbit LIGHT=P1^5;  //报警灯
sbit dp=P2^7;
uchar x;            //计数值
uchar anci ;       //按下SET键的次数
uchar m;           //温度值
uchar n;              //温度值
uchar h=35;
uchar l=27;         //上下限温度值

uchar code led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
void delay(uint num)
{
   while(num--);

}
void initds18b20()          //初始化ds18b20
{
  uchar g=0;
  P2=0x00;
  DQ=1;
  delay(8);
  DQ=0;
  delay(80);
  DQ=1;
  delay(14);
  g=DQ;
  delay(20);
                            
}
void inittimer0(void)  //初始化定时器0
        {
          TMOD=01;
          TH0=0x3c;
          TL0=0xb0;
       
        }

void timer0(void) interrupt 1 //定时器0服务子程序
{
        TH0=0x3c;
        TL0=0xb0;
        x++;


}
void int0(void) interrupt 0                   //外部中断0服务子程序
{
  EX0=0; //关外部中断0
  if(DEC==0&&(anci==1||anci==2))
  {
          delay(200);         //延时去抖
        if(DEC==0&&anci==1)
        {
           h--;
           if(h<l)
           h=l;
       
       
        }

        else if(DEC==0&&anci==2)
        {
          l--;
          if(l<0)
          l=0;
       
        }

  
  
  }


}

void int1(void)        interrupt 2                //外部中断1服务子程序
{
  EX1=0         ;  //关外部中断1
  if(ADD==0&&(anci==1||anci==2))
  {
          delay(210) ;
           if(ADD==0&&anci==1)
         {
                 h++;
                if(h>99)
                h=99;
         
         }
           else if(ADD==0&&anci==2)
         {
                  l++;
                 if(l>h)
                 l=h;

         
         
         }
  }


}

void writeonechar(uchar dat)          //写一个字节
{

  uchar i;

  for(i=0;i<8;i++)
        {       
             DQ=0;
                 DQ=dat&0x01;
                 delay(8);
                 DQ=1;
                 dat>>=1;

           }

}
unsigned char readonechar(void)          //读一个字节
{
   uchar j;
   uchar dat=0;
   for(j=0;j<8;j++)
   {
            DQ=0;
         dat>>=1;
         DQ=1;
         if(DQ==1)
         dat=dat|0x80;
     delay(4);
    }

   return(dat);

}
unsigned int readtemperature()         //读取温度
{
  uchar a=0;
  uchar b=0;
  uint  t=0;
  float tt=0;                        //初始化ds18b20
  initds18b20();
  writeonechar(0xcc);  // 跳过读序列号操作
  writeonechar(0x44);  //启动温度转换
  initds18b20();
  writeonechar(0xcc);
  writeonechar(0xbe);  //读取温度寄存器
  a=readonechar();
  b=readonechar();
  t=b;
  t<<=8;
  t=t|a;
  tt=t*0.0625 ;                   //得到真正的温度值
  t=tt*10+0.5;                 //放大10倍,便于显示
  return(t);



}

void checktemperature()                  //检测温度
{
  uint a,b,c;
  c=readtemperature()-5 ;          //温度误差
  a=c/100;                //得到真实温度的十位,因为之前扩大了十倍
  b=c/10-a*10;                    //得到个位
  m=c/10;                // 得到整数位
  n=c-a*100-b*10;         //得到小数位
  if(m<0)
  {
    m=0;
    n=0;
   }
   if(m>99)
   {
           m=99;
        n=9;
   
   }





}


void dis_init()                         //显示开机画面,当开机时所有的数码管都显示1
{
   P2=0x06;                     //显示1
   P0=0xfe;
   delay(200);                         //为数码管动态显示

   P0=0xfd;
   delay(200);

   P0=0xfb;
   delay(200);

   P0=0xf7;
   delay(200);

   P0=0xff;


}
void disp_temperature()
{
  P0=0xf7;
  P2=0x39;                         //显示C
  delay(200);
   
  P0=0xfb;
  P2=led[n];   //显示小数位
  delay(200);

  P0=0xfd;
  P2=led[m%10];                        //显示个位
  dp=1;                       //显示小数点
  delay(200);

  P0=0xfe;
  P2=led[m/10];                         //显示十位
  delay(200);

  P0=0xff;



}

void disp_alarm(uchar warnning)           //显示上下限温度警告值
{
  P0=0xf7;                        //显示C
  P2=0x39;
  delay(200) ;
   
  P0=0xfb;                                 //小数位
  P2=led[warnning%10];
  delay(200);

  P0=0xfd;
  P2=led[warnning/10];           //十位
  delay(200);
   
  if(anci==1)
  {
          P0=0xfe;                 //显示H 上限
        P2=0x76;
        delay(200);
  }
   if(anci==2)
   {
            P0=0xfe;
         P2=0x38;
         delay(200);        //显示L 下限
   
   }

   P0=0xff;

}

void alarm()           //报警子程序
{
if(l<m&&m<h)
{
   BEEP=1;
  LIGHT=1;

}
else if(m<=l||m>=h)
{
   BEEP=0;
   LIGHT=0;


}


}                  

void main()
{
   uchar z;
   inittimer0();
   EA=1;         //开总中断
   TR0=1;        //启动定时器0,开始计数
   ET0=1;        //开启定时器0中断允许
   IT0=1;                 //外部中断0为跳变沿触发
   IT1=1;         
   checktemperature();
   for(z=100;z>0;z--)
     {
                
           dis_init();
         
         }
         while(1)
         {
          if(SET==0)
            {
                  delay(200);   //延时去抖
                  do{}while(SET==0);  //先执行{}一次再判断(条件)如果为真则执行,如果一直按着,则循环下去
                  anci++;
                  x=0;
                  f_biao=1;
                  if(anci>2)
                   anci=0;
               
               
               
                }
                if(anci==0)
                {
                  EX0=0;                                        //关中断
                  EX1=0;
                  checktemperature();                //检测温度
                  disp_temperature();                //显示温度
                  alarm();                //报警检测
               
                }

                if(anci==1)
                {
                  EX0=1;                                   //开中断
                  EX1=1;
                  BEEP=1;
                  LIGHT=1;
                  if(x>10)
                  {
                          f_biao=~f_biao;
                        x=0;
                  
                  
                  }
                  if(f_biao)
                  {
                          disp_alarm(h);                  //按一次 显示上限温度
                  }
                  
                    }
           if(anci==2)
           {
                     BEEP=1;
                  LIGHT=1;
                  EX0=1;
                  EX1=1;
                  if(x>10)
                  {
                           f_biao=~f_biao;
                         x=0;
                  
                  }
                  if(f_biao)
                  {
                          disp_alarm(l);                                 //按两次显示下限温度
                  }
          
           }

        }

}
/****THE END*****/
//成功啦!!!!!!










友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
大呵欠E
2020-02-02 21:22
lcw_swust 发表于 2012-10-31 09:20
do{}while(SET==0);  
当SET=0的时候,程序在此死循环,自然不会往下执行disp_temperature();             ...

很高兴你能指教,但我还有很多问题不懂。。为什么我用该程序能够仿真的出来了呢?还有这个do{}while(set==0)语句不是要该按键按下去SET==0才会是低电平的吗?他才执行{}里语句,也只有我按下去的时候才为低电平啊,我不按就为高电平了 他就不满足while()后的条件 不是就跳出这个语句了吗?好像不可能在这死循环啊。。。不解,还需高人点拨才行。。

一周热门 更多>