⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zhoujian.c

📁 烟度控制仪源程序。。希望大家能实用下
💻 C
字号:
#include <reg52.h>
#include <absacc.h>
#define uchar unsigned char
#define uint  unsigned int      
#define ulong  unsigned long
#define CSKEY XBYTE[0x0080]                      //键盘
#define CSBIT XBYTE[0x0081]                      //位选
#define CSSEG XBYTE[0x0082]                      //段选
#define OLE1  XBYTE[0x0083]
#define Baud  0xf4                      //计数初值
#define ADDR  0                         //YDY地址
sbit P10=P1^0;       //data
sbit P12=P1^2;       //clock
sbit P11=P1^1;       //latch
sbit P33=P3^3;       ///INT1  h1
sbit P34=P3^4;       //T0   h2
bit judge1,dd1,dd2;        //       ++++++++
bit ss;                    //串口接收标志
uchar seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,   0x08,0x06,0xc6,0xff,0x7f,0xbf,0x0e,0x03};    //数码管
            // 0    1     2    3    4    5    6    7    8    9    //"A.""E." "C" " "  " ."  "-" "F.""b."
uchar aa,bb,cc;                //测试时数码管显示暂存
uchar dSegD[8]=0xff;                //显示段码内容存放
uchar Tt[4];                   //测量结果 Tt[0]:均值
uchar TtHD;                           //结果指针 0:无测量 1~3:结果
uchar Md;                             //最大差值
uchar sbuffer[4];              //串口缓冲区
uchar sbufferpt;               //缓冲区指针
uchar sbuftemp;
uchar accTime;            //加速测试定时器计数

void delay(uint t)
{ while(t--);                  //22+11*t us延时
}
void delayl(uint t)
{ uchar i;
  for(i=0;i<t;i++)
  {  delay(0xffff);                 // 0.721*t S延时
  }
}
uchar Mdpr(uchar a,b,c)                  //求三数最大差值
{ uchar M,S;
  if(a>b){M=a;S=b;}
  else{M=b;S=a;}
  if(M<c){M=c;}
  else if(S>c){S=c;}
  return(M-S);
}

//------------------------------------------------------------

void initD()                         //数据初始化
{ Tt[0]=0;Tt[1]=0;Tt[2]=0;Tt[3]=0;
  TtHD=0;
  Md=0;
  accTime=0;
}
void initS()
{ SCON=0;
  TCON=0;
  IE=0;
}

void initSB()
{ sbuffer[0]=0;sbuffer[1]=0;sbuffer[2]=0;sbuffer[3]=0;   //串口缓冲区
  sbufferpt=0;
  sbuftemp=0;
  ss=0;                                      //串口接收标志
}
//---------------------------------------------------------------
void SgBtOut(uchar s,b)
{ CSSEG=s;
  CSBIT=b;
}
void TstDspP(uchar a,b,c)                //测试时数码管显示准备
{ uchar temp;

  aa=a;bb=b;cc=c;
  //if (a>=4) ah=seg[10];
  //else ah=seg[a];
  dSegD[0]=seg[aa];
  dSegD[1]=0xff;
  temp=bb/10;
  dSegD[2]=seg[temp]&0x7f;     //加小数点
  temp=bb%10;
  dSegD[3]=seg[temp];
  dSegD[4]=0xff;
  dSegD[5]=0xff;
  temp=cc/10;
  dSegD[6]=seg[temp]&0x7f;     //加小数点
  temp=cc%10;
  dSegD[7]=seg[temp];
}
void dsply2p(uchar j1,d1,d2)
{ judge1=j1;dd1=d1;dd2=d2;
}
void dsply()
{ uchar i;
  uchar b=0x01;         //位选
  for(i=0;i<7;i++)
  { SgBtOut(dSegD[i],b);
    delay(20);
    b=b<<1;
  }
  SgBtOut(dSegD[7],b);
  delay(10);
}
dsply2()
{  if(judge1==0)
     { if(dd2==0) OLE1=0xff;
       else OLE1=0xef;
     }
   else if (dd1) OLE1=0xfb;        //0xf7 错误; 0xfb 正确;
        else OLE1=0xf7;
}

void Idsply(uchar i,d)
{ uint t;
  dSegD[0]=seg[i];dSegD[1]=0xff;dSegD[2]=0x7f;dSegD[3]=seg[d];
  dSegD[4]=0xff;dSegD[5]=0xff;dSegD[6]=0xff;dSegD[7]=0xff;
  t=0x500;
  while(t--)      //显示3 s
  { dsply();
  }
  TstDspP(TtHD,Tt[TtHD],Md);
}

void dsplytemp()       //4.2s显示当前烟度值
{ uint t;
  t=0x0800;
      while(t--)
      {dsply();
      }
}
void waitDspP()     //等待状态显示:两点
{ SgBtOut(0x7f,0x44);
  //OLE1=0xff;
}

//-----------------------------------------------------------------

void receive(void) interrupt 4 using 3
  {  RI=0;
     ss=1;
     sbuftemp=SBUF;
     sbuffer[sbufferpt++]=sbuftemp;       //以后改为工作寄存器之类的存储
  }

void OutToSBF(bit tb,uchar x)        //串口输出
{ TB8=tb;
  SBUF=x;
  while(!TI);
  TI=0;
}

void testM()
{ uint t;//t1;

  SCON=0xc0;            //方式3,不允许接收,SM2=0
  TMOD=0x20;            //TIMER1 工作于方式2
  TH1=230;              //波特率 1200
  TR1=1;                //启动TIMER1
  ET1=0;                //关回0中断
  ES=0;
  EA=0;

  OutToSBF(1,ADDR);    //-----地址帧-----

 //++++++++++++++++++检查烟度仪准备好否+++++++++++++++++++
  REN=1;                //准备接收 SCON=0xd0;  串行方式3,sm2=0,REN=1;
  IE=0x90;              //ES=1;EA=1; 开接收中断
  t=0;
  ss=0;
  while((!ss)&&(t<32000))//0.4s 超时
  {t++;}
  IE=0;                 //关中断
  REN=0;
  if(!ss)Idsply(11,1);   //+++++++ 1#号错误:烟度yi没准备好 ++++++++++++++++++++++++
  else
  {
  OutToSBF(0,0xc0);     //-----数据帧 复位命令--------
  delayl(1);         //0.7 mS延时
  OutToSBF(1,ADDR);     //-----地址帧 -------
  OutToSBF(0,0x88);     //-----数据帧 测量命令--------
  delayl(16);          //11s~12s
  /*
  //============测完判断===============//
  t1=0;
  sbuftemp=0;
  while((!(sbuftemp&0x01))&&(t1<15))   //0.7+0.4s查询一次,共15次,>16s
  {
  OutToSBF(1,ADDR);       //----------地址帧------------
  OutToSBF(0,0xa0);       //-----数据帧 返回状态码命令-----
  REN=1;                //准备接收 SCON=0xd0;  串行方式3,sm2=0,REN=1;
  IE=0x90;              //ES=1;
                        //EA=1;
  sbuftemp=0;
  ss=0;
  t=0;
  while((!ss)&&(t<32000))      //0.4s 接收状态码
  { t++;                       //
  }
  REN=0;
  IE=0;
  t1++;
  delayl(1);                   //0.7s延时
  }
  //=======================================//

  if(t1==15)Idsply(11,2); //++++++++++++++ 2#错误,YDY测量超时+++++++++++
  else
  {
  REN=0;IE=0;
  delayl(1);            //让前面的数据超时失效,为后面的数据准备
  */
  OutToSBF(1,ADDR);       //----------地址帧------------
  OutToSBF(0,0x90);       //-----数据帧 返回数据命令-----

  REN=1;                //准备接收 SCON=0xd0;  串行方式3,sm2=0,REN=1;
  IE=0x90;              //ES=1;
                        //EA=1;
  sbuftemp=0;
  sbufferpt=0;          //t=0;
  t=0;
  while((sbufferpt<3)&&(t<32000))      //while((i<3)&(t<200))
  { t++;                            //{ t++;
  }                                   //}
  initS();                         //串口复位

  if(t==32000)Idsply(11,3);            // 3#错误:串口接收测量结果超时0.4s
    //...判断正确否
    //
    //
  else
  {
    switch (TtHD)
    { case 3:initD();TtHD=1;Tt[1]=sbuffer[1];break;
      case 2:Tt[++TtHD]=sbuffer[1];Md=Mdpr(Tt[1],Tt[2],Tt[3]);break;    //+++++++++++++++++
      case 1:Tt[++TtHD]=sbuffer[1];Md=(Tt[1]>Tt[2])?(Tt[1]-Tt[2]):Tt[2]-Tt[1];break;
      case 0:Tt[++TtHD]=sbuffer[1];Md=0;break;
    }
    if(TtHD!=0)
    { if(Md>3)dd1=0;
      else dd1=1;
      judge1=1;
    }
    else judge1=0;
  }
  //}
 }
  dd2=0;
  TstDspP(TtHD,Tt[TtHD],Md); //aa=TtHD; bb=Tt[TtHD];cc=Md;
  initSB();               //串口缓冲区复位
}

void testA()
{  testM();dsplytemp();waitDspP();
   testM();dsplytemp();waitDspP();
   testM();
}

//-----------------------------------------------------------

void del()
{
  switch(TtHD)
  { case 0:break;
    case 1:initD();break;//Tt[TtHD--]=0;Md=0;break;//Tt[0]=0;
    case 2:Tt[TtHD--]=0;Md=0;break;//Tt[0]=Tt[1];
    case 3:Tt[TtHD--]=0;Md=(Tt[1]>Tt[2])?(Tt[1]-Tt[2]):(Tt[2]-Tt[1]);break;
  }
  if(TtHD!=0)
  {  if(Md>3)dd1=0;
     else dd1=1;
     judge1=1;}
  else judge1=0;
  dsply2p(judge1,dd1,0);
  TstDspP(TtHD,Tt[TtHD],Md);//aa=TtHD;bb=Tt[TtHD];cc=Md;
}

//---------------------------------------------------------

void avr()
{ uchar i;
  i=TtHD;
  Tt[0]=0;
  while(i)
  { Tt[0]+=Tt[i--];
  }
  if(TtHD!=0)Tt[0]=Tt[0]/TtHD;
  TstDspP(10,Tt[TtHD],Md);//aa=10;bb=Tt[TtHD];cc=Md;
  dsply2p(0,0,0);
}
//---------------------------------------------------------

void sendlatch()
{ P11=0;                  ______ 
  delay(900);             |    |
  P11=1;                  |    |
  delay(900);        _____|    |
}                      
void senddata(uchar a1)        // ++++++++++
{ bit s;
  uint a;   uchar i=16;
  sendlatch();
  //P11=0;
  //P11=1;
  a=a1*35;                      //类型转换
  a=a/100;
  a=a+a1*655;
  while(i--)
  { if(a&0x8000) s=1;
    else s=0;
    P10=s;
    delay(900);   //等待数据有效
    P12=0;
    delay(900);   //等待放电完成
    P12=1;
    a=a<<1;
    delay(900);
  }
  sendlatch();
}
void send()
{ uchar i,daNO;
  for(i=0;i<=3;i++)
    { daNO=i|0xfc;
      OLE1=daNO;                  //选通所要发送的DA    1#:平均值  2~4#:测量值
      delay(10000);
      senddata(Tt[i]);
  }
  dsply2p(0,0,1);        //led1灭
                         //led2亮
/*
  for(i=0;i<30;i++)
  {  delay(10000);                 //60*i mS延时
  }
  */
}
//------------------------------------------------------------

void save()                    //****************
{
  OLE1=0x7f;
  delayl(3);
  OLE1=0xff;                    //复位
  initD();
  initS();initSB();
  dsply2p(0,0,0);
  TstDspP(TtHD,Tt[TtHD],Md);
}
//---------------------------------------------------------

uchar Jkey()
{ uchar key,key1,key2;
  uint t;

  key1=CSKEY;
  key1=key1&0x3f;
  if(key1!=0x3f)                //有键按下
  {     //waitDspP();
        delay(1500);            //10mS左右去抖
        waitDspP();
        key1=CSKEY;              //读稳定值
        key1=key1&0x3f;
        if(key1!=0x3f)
        { key2=key1;             //保存
          delay(500);
          key1=CSKEY;
          key1=key1&0x3f;
          if(key1==key2)         //按的同一键
          { key=key1;
            t=0;
            while(key1!=0x3f)    //等松手
            { key1=CSKEY;
              key1=key1&0x3f;
              if(t<65535)t++;
            }
            if(t>30000)
            { if(key2==0x3e)key=0x11;
              if(key2==0x3d)key=0x22;
              if(key2==0x1f)key=0x66;
            }
          }
        }
  }
  else key=0;
  return(key);
}
//---------------------------------------------------------------

void accP()
{ bit r;
  uint t;

  SgBtOut(0xbf,0x01);
  r=0;    //
  IE=0;
  while(!r)
   { switch(Jkey())
     { case  0x3b: SgBtOut(0x0e,0x01);
                   t=0;
                   OLE1=0xff;//电源不接通24v 靠弹簧向前  //OLE1=0xdf; //电源接通24v 向前
                   while((P34==1)&&(t<34000))    //1.4s
                   {t++;}
                   if(t==34000)Idsply(11,4);        //++++++++4#错误:活塞无法回起始点+++++++
                   SgBtOut(0x0e,0x01);
                   break;
       case  0x37:SgBtOut(0x03,0x01);
                  t=0;
                  OLE1=0xbf;
                  OLE1=0x9f;                  //活塞向后拉
                  while((P33==1)&&(t<34000))
                  {t++;}  //s
                  if(t==34000)Idsply(11,6);           //6#错误:活塞向后拉杆超时,汽缸问题
                  SgBtOut(0x03,0x01);
                  break;
       case  0x3d:OLE1=0xff;r=1;initD();break;
       default:break;
     }
   }

}
//---------------------------------------------------------------
void accout(void) interrupt 2 using 2
{ TR2=0;         //停定时器
  F0=1;          //测试结束标志
}
void timer2(void) interrupt 5 using 3
{ TF2=0;
  accTime++;
}

void acctestM()                 //人工
{ uint t;
  ulong accT;   //总时间结果
  accTime=0;
  OLE1=0xff;                    //电源不接通24v 靠弹簧向前
  delayl(1);                    //    向前0.7s左右
  if(P34==1)Idsply(11,4);        //4#错误:活塞无法回起始点
  else
  { T2CON=0;
    TH2=0;
    TL2=0;
    F0=0;
    t=0;
    OLE1=0xbf;                  //向后拉
    OLE1=0x9f;                  //并接通24v
    while((P34==0)&&(t<34000))  //等离开H2(T0)     加超时判断 1.4s
    {t++;}
    if(t==34000)Idsply(11,5);   //++++++++++ 5#错误:活塞无法离开起始点++++++++++
    else{
    TR2=1;                      //开始计时
    TCON=0x04;                  //INT1下降沿触发
    IP=0x04;                    //INT1高优先,TIMER低优先
    IE=0xa4;                    //TIMER2开溢出中断,开INT1中断,开cpu中断
    while((!F0)&&(accTime<50));  //3.2s
    IP=0;
    IE=0;
    if(!F0)Idsply(11,6);           //6#错误:活塞向后拉杆超时,汽缸问题
    else                                                              //  ---------
    {                                                                 //
        accT=accTime*65536+TH2*256+TL2;                               //   数据处理
        accT=accT/1000;         //舍去us部分                          //
        for(t=0;t<=3;t++)                                             //
        { dSegD[7-t]=seg[accT%10]; accT=accT/10;                      //
        }                                                             //
        dSegD[0]=0x88;dSegD[1]=0xc6;dSegD[2]=0xc6;dSegD[3]=0xff;      //
                                                                      //  ----------
      dsplytemp();         //4.2s显示拉杆时间
      waitDspP();
      OLE1=0xff;           //向前拉
      testM();
      dsplytemp();        //4.2s显示烟度值
    }
    }
  }
  OLE1=0xff;                    //复位

  TstDspP(TtHD,Tt[TtHD],Md);
  dsply2p(0,0,0);
}
void acctestA()                 //自动
{
   initD();
   acctestM();acctestM();acctestM();
   //avr();
}

//--------------------------------------------------------

main()
{
  SgBtOut(0x00,0xff);           //数码管检查
  OLE1=0xff;                    //控制端初始化
  initD();                      //测量结果初始化
  initS();                      //串口初始化
  initSB();
  //OLE1=0xff;                    //控制端初始化
  send();                       //DA初始化送0
  send();
  TstDspP(0,0,0);
  dsply2p(0,0,0);

  while(1)                        //查询
  {
        switch(Jkey())
           { case 0x3e   :testM();break;      //1
             case 0x3d   :del();break;        //2
             case 0x3b   :avr();break;        //3
             case 0x37   :send();break;       //4
             case 0x2f   :save();break;       //5***********
             case 0x1f   :acctestM();break;   //6
             case 0x66   :acctestA();break;   //66
             case 0x22   :accP();break;       //22      加速调试
             case 0x11   :testA();break;      //11
             default: break;
           }
    dsply();
    dsply2();

  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -