我寫的市電、發電機組供電自動轉換控制櫃單片機程序

#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);
    }
   //-----------------------------------------------------------------------------------------
  }
}
//--------------------------------------------------------------------------------------------
發佈了33 篇原創文章 · 獲贊 10 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章