#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);
}
//-----------------------------------------------------------------------------------------
}
}
//--------------------------------------------------------------------------------------------
#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);
}
//-----------------------------------------------------------------------------------------
}
}
//--------------------------------------------------------------------------------------------