我写的市电、发电机组供电自动转换控制柜单片机程序

来源:互联网 发布:mac解压软件 知乎 编辑:程序博客网 时间:2024/05/16 19:48
#include <AT89X51.H>
#include <absacc.h>
#include <intrins.h>
#define uchar unsigned char
#define COM8155 XBYTE[0xfdf8]                     //8155命令口地址
#define PA8155 XBYTE[0xfdf9]                      //8155口A地址
#define PB8155 XBYTE[0xfdfa]                      //8155口B地址
sbit p10=P1^0;
sbit p11=P1^1;
sbit p12=P1^2;
sbit p13=P1^3;
sbit p14=P1^4;
sbit p15=P1^5;
sbit p16=P1^6;
sbit p17=P1^7;
sbit p20=P2^0;
sbit p21=P2^1;
sbit p22=P2^2;
bit me_flag=0;
bit de_flag=0;
bit urs_flag=0;
bit flag_8155=0;
unsigned int idata num=0;
unsigned int t=50000;
uchar ml,mh,hh,hl;                                //hh hl:mh ml
uchar code x[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0,1,2,3,...,9
//--------------------------------------------------------------------------------------------
void TimeToScrn(uchar idata hhmm,uchar idata sel) //8155时间处理子函数
{
 PA8155=sel;
 PB8155=x[hhmm];
 _nop_();_nop_();_nop_();
}
//--------------------------------------------------------------------------------------------
void Interrupt_0() interrupt 0 using 1            //外部中断0子函数--市电和发电机组同时有电
{
 P1=(P1&0xe0)|0x1f;                               //切断所有可能输出
 while(t--);t=50000; while(t--);t=50000;          //延时200ms
 //-------------------------------------------------------------------------------------------
 while(p17==0)
  {
   P1=(P1|0x04)&0xe4;                             //接通市电, 停机组,直到机组停机成功
   while(t--);t=50000; while(t--); t=50000;       //延时200ms
  }
 TR0=0;                                  
 P1=(P1|0x07)&0xe7;                               //保持市电接通状态
 me_flag=1;
 de_flag=0;
 //-------------------------------------------------------------------------------------------
 p21=1;                                           //8155停止工作
 flag_8155=0;
 P2=(P2&0x1f)|0xe0;                               //市电指示灯亮(111x xxxx)
}
//--------------------------------------------------------------------------------------------
void Interrupt_2() interrupt 2 using 2            //紧急停机组(中断优先)
{
 if(de_flag==1)
  {
   P1=(P1&0xe0)|0x1f;                             //切断所有可能输出
   while(t--);t=50000; while(t--); t=50000;       //延时200ms
   while(p17==0)
    {
     P1=(P1|0x1c)&0xfc;                           //停机组,直到发电机组停机成功
     while(t--); t=50000;while(t--); t=50000;     //延时200ms
    }
   P1=(P1&0xe0)|0x1f;                             //切断所有可能输出;           
   de_flag=0;
   p21=1;                                         //机组运行时间显示停
   flag_8155=0;
   urs_flag=1;
   TR0=0;                            
   P2=(P2&0x1f)|0xa0;                             //转换失败报警(101x xxxx) 
  }
}
//--------------------------------------------------------------------------------------------
void Time0_int() interrupt 1 using 1              //定时器0中断
{
 TH0=(65536-40000)/256;                           //20ms 中断周期,共中断3000次,显示1分钟
 TL0=(65536-40000)%256;
 num++;
 if(num>3000)
  {
   num=0;ml++;
   if(ml>9)
    {
     ml=0;mh++;
     if(mh>5)
      {
       mh=0;hl++;
       if(hl>9)
        {
         hl=0;hh++;
         if(hh>9)
          hh=0;
         TimeToScrn(hh,0x08);
        }
       TimeToScrn(hl,0x04);
      }
     TimeToScrn(mh,0x02);
    }
   TimeToScrn(ml,0x01);
  }
}
//--------------------------------------------------------------------------------------------
void  Init()
{
 me_flag=0; de_flag=0;urs_flag=0;flag_8155=0;
 num=0;ml=0;mh=0;hh=0;hl=0;
 //IE=0x85;            
 EA=1;                                            //全部中断允许
 EX0=1;                                           //外部中断0允许 市电、油机同时有电中断允许
 EX1=1;                                           //外部中断1允许 紧急停发电机组中断允许
 ET0=1;                                           //定时器0中断允许
 IP=0x04;                                         //置外部中断1优选(紧急停发电机组优先)
 TMOD=0x01;                                       //定时器0方式1,仅受TR0控制
 TH0=(65536-40000)/256;                           //20ms 中断周期,共中断3000次,表示1分钟
 TL0=(65536-40000)%256;
 TR0=0;                                           //定时器0停止工作
 P1=0xff;                                         //p15=1、p16=1、p17=1准备读入
 P2=0x0f;                                         //8155 禁止、置8155 I/O 模式
}
//--------------------------------------------------------------------------------------------
void main(void)                                   //主程序
{
 uchar idata startnum=0;
 uchar i,sel;
 sel=0x01;
 t=50000;
 Init();
 while(1)
  {
   //-----------------------------------------------------------------------------------------
   if(p20==0&&flag_8155==1)                       //发电机组运行时间显示复位请零
    {
     COM8155=0x0b;                                //送命令字 口A送位码 口B送段码
     for(i=0;i<4;i++)                             //显示清零
      {
       TimeToScrn(0,sel);
       sel=sel<<1;
      }
     TR0=0;
     ET0=0;
     num=0;ml=0;mh=0;hh=0;hl=0;
     TR0=1;
     ET0=1;
    }
   //------------------------------------------------------------------------------------------
   //市电停或没市电,且紧急停机故障已修复
   if(p15==1&&p16==0&&urs_flag==0)
     {
      me_flag=0;                                  //置市电接通标志非
      startnum=0;                                
      //--------------------------------------------------------------------------------------
      while(p17==1)                            //监测发电机组启动成功与否
       {
        //------------------------------------------------------------------------------------
        P1=(P1&0xe0)|0x1f;                        //切断所有可能输出
        TR0=0;
        if(startnum>2)                            //已连续启动发电机组三次
         break;
        //------------------------------------------------------------------------------------
        P1=(P1|0x13)&0xf3;                        //启动发电机组
        while(t--); t=50000;while(t--);t=50000;   //延时1s
        while(t--); t=50000;while(t--);t=50000;
        while(t--); t=50000;while(t--);t=50000;
        while(t--); t=50000;while(t--);t=50000;
        while(t--); t=50000;while(t--);t=50000;       
        //------------------------------------------------------------------------------------
        P1=(P1&0xe0)|0x1f;
        startnum++;
       }
      if(p17==1)                                  //若发电机组启动失败
       {
        P2=(P2&0x1f)|0xa0;                        //转换失败报警(101x xxxx) 
        de_flag=0;
        P1=(P1&0xe0)|0x1f;                        //切断所有可能输出 
       }
      else if(p17==0&&de_flag==0)                 //若发电机组启动成功且发电机组未接通
       {
        P1=(P1&0xe0)|0x1f;                        //切断所有可能输出
        while(t--); t=50000;while(t--);t=50000;   //延时200ms
        P1=(P1|0x19)&0xf9;                        //使能发电机组输出
        de_flag=1;        
        TH0=(65536-40000)/256;                    //20ms 中断周期,共中断3000次,表示1分钟
        TL0=(65536-40000)%256;
        P2=(P2&0x1f)|0xc0;                        //发电机组输出指示灯亮(110x xxxx)
        p21=0;                                    //8155 使能,发电机组工作时间显示开始
        flag_8155=1;                              //8155使能标志置1
        p22=1;                                    //置8155 I/O 状态 
        COM8155=0x0b;                             //送命令字 口A送位码 口B送段码
        for(i=0;i<4;i++)                          //显示清零
         {
          TimeToScrn(0,sel);
          sel=sel<<1;
         }
        ET0=1;                                    //定时器 0中断允许
        TR0=1;                                    //启动定时器0
       }
      else if(p17==0&&de_flag==1)                 //若发电机组运行中且发电机组已接通
        P2=(P2&0x1f)|0xc0;                        //发电机组输出指示灯亮(110x xxxx)
     }
   //-----------------------------------------------------------------------------------------
   //市电有电且发电机组未启动,市电未接通时
   else if(p15==0&&p16==1&&p17==1&&me_flag==0)   
     {
      me_flag=1;                                  //置市电输出标志量1
      de_flag=0; 
      P1=(P1&0xe0)|0x1f;                          //切断所有可能输出
      while(t--); t=50000;while(t--);t=50000;     //延时200ms
      P1=(P1|0x07)&0xe7;                          //接通市电输出
      P2=(P2&0x1f)|0xe0;                          //市电输出指示灯亮 (111x xxxx)
     }
   //-----------------------------------------------------------------------------------------
   //市电有电且发电机组未启动,市电已接通时
   else if(p15==0&&p16==1&&p17==1&&me_flag==1)
     P2=(P2&0x1f)|0xe0;                           //市电输出指示灯亮 (111x xxxx)
   //-----------------------------------------------------------------------------------------
   //未知情况
   else
    {
     while(t--); t=50000;while(t--);t=50000;      //延时200ms
     P1=(P1&0xe0)|0x1f;                           //切断所有可能输出
     while(t--); t=50000;while(t--);t=50000;      //延时200ms
     P2=0x0f;                                     //关掉所有指示灯
     TR0=0;                    
     //while(1);
    }
   //-----------------------------------------------------------------------------------------
  }
}
//--------------------------------------------------------------------------------------------
原创粉丝点击