一、 原理簡(jiǎn)介
該方案的框圖如下:
山頂機(jī)房及山下機(jī)房各安裝一塊控制板,兩者之間通過(guò)專(zhuān)線MODEM相連。山下控制板主要功能是:將操作人員的開(kāi)關(guān)信息轉(zhuǎn)換成指令,發(fā)送給山頂控制板,并根據(jù)山頂控制板發(fā)來(lái)的電源通斷狀態(tài)報(bào)告指令,以指示燈的形式顯示給操作人員。山頂控制板主要功能是:通過(guò)控制繼電器的吸放來(lái)控制設(shè)備的電源,該板在接收到山下控制板發(fā)來(lái)的開(kāi)關(guān)電指令后,驅(qū)動(dòng)繼電器的吸放,并將繼電器的反饋狀態(tài)轉(zhuǎn)換成指令,報(bào)告給山下控制板。兩處的專(zhuān)線MODEM由本單位內(nèi)部的光纖通信設(shè)備提供的音頻線路連接。
二、山頂控制板
山頂控制板所包括的主要元件有單片機(jī)芯片89C2051,電平轉(zhuǎn)換芯片MAX232,電源模塊。由于需遙控的通信設(shè)備使用-48V電源,山頂控制板也采用-48V。該板采用了一個(gè)成品開(kāi)關(guān)電源模塊,將-48V轉(zhuǎn)換成+5V。芯片MAX232的功能是把單片機(jī)串口的TTL電平轉(zhuǎn)換成MODEM的RS-232電平,使單片機(jī)能通過(guò)MODEM收發(fā)數(shù)據(jù)。2051單片機(jī)根據(jù)山下控制板發(fā)來(lái)的指令,通過(guò)P1_4腳控制線圈電壓為5V的小繼電器RY1的吸放,進(jìn)而控制電源繼電器RY2的吸放。電源繼電器RY2為兩組觸點(diǎn)、24V線圈電壓的大繼電器,觸點(diǎn)可承受較大電流。其中的一組觸點(diǎn)用于控制設(shè)備電源的通斷,接中間觸點(diǎn)及常閉觸點(diǎn)。繼電器釋放時(shí),設(shè)備加電,繼電器吸合時(shí),設(shè)備關(guān)電。另外一組觸點(diǎn)作為繼電器動(dòng)作后的反饋,接中間觸點(diǎn)及常開(kāi)觸點(diǎn),分別接地及2051的P1_7腳。當(dāng)繼電器RY2吸合時(shí)P1_7經(jīng)繼電器接地,為低電平,繼電器釋放時(shí)P1_7腳為高平(2051內(nèi)部有上拉電阻)。單片機(jī)2051每秒鐘檢測(cè)一次P1_7腳是否接地,以此判定繼電器是否吸合(即是否斷開(kāi)了設(shè)備的電源),隨后將檢測(cè)的結(jié)果轉(zhuǎn)換成指令,通過(guò)MODEM向山下的控制板匯報(bào),同時(shí)本身的斷電指示燈也顯示出設(shè)備的加斷電狀態(tài)。
山頂控制板的電路圖如下:
山頂控制板的程序如下:
#include "atmelAT89X51.H"
#define SYN 'Z' //來(lái)自山下控制板數(shù)據(jù)幀的同步字符
char countdown; //時(shí)間計(jì)數(shù)
char TX_buf[3]; //發(fā)送緩沖區(qū)
char TX_len; //發(fā)送字符串長(zhǎng)度
char TX_num;
char RX_buf[3]; //接收緩沖區(qū)
char RX_len; //接收字符串長(zhǎng)度
char RX_num;
char CRC(char *buf,char len) //校驗(yàn)碼生成函數(shù)
{char i,temp;
temp=0;
for(i=0;i<len;i++) temp=temp^buf[i];
return(temp);
}
void timer0_int() interrupt 1 //定時(shí)器0的中斷服務(wù)程序
{ TL0=0x00; TH0=0x0A6;
countdown--;
if(countdown==0 || countdown==20)
P1_0=!P1_0; //控制CPU運(yùn)行指示燈的秒閃
if(countdown!=0) return;
countdown=40; //過(guò)了一秒鐘
P3_7=P1_7; //檢測(cè)電源繼電器的吸放狀態(tài),并驅(qū)動(dòng)P3_7的指示燈
if(P1_7) TX_buf[1]=0x13; //高電平,電源繼電器已釋放,設(shè)備電源接通
else TX_buf[1]=0x31; //接地,電源繼電器已吸合,設(shè)備電源中斷
TX_buf[2]=CRC(TX_buf,2); //生成校驗(yàn)碼
TX_num=0;
SBUF=TX_buf[0]; //向山下控制板報(bào)告繼電器的吸放狀態(tài)
}
void serial_int() interrupt 4 //串口中斷服務(wù)程序
{ if(TI) //發(fā)送觸發(fā)了中斷
{ TI=0; TX_num++;
if(TX_num<TX_len) SBUF=TX_buf[TX_num];
}
else //接收觸發(fā)了中斷
{ RI=0; RX_buf[RX_num]=SBUF;
if(RX_num==0 && RX_buf[RX_num]!=SYN)
return; //在接收的數(shù)據(jù)中搜索同步字符
RX_num++;
if(RX_num==RX_len) //收完一條指令
{ RX_num=0;
if(RX_buf[RX_len-1]==CRC(RX_buf,RX_len-1)) //檢查校驗(yàn)碼是否正確
{ if(RX_buf[1]==0x13) P1_4=1; //釋放小繼電器RY1及電源繼電器RY2
if(RX_buf[1]==0x31) P1_4=0; //吸合小繼電器RY1及電源繼電器RY2
}
}
}
}
void main()
{ IE=0x92;
TMOD=0x21; //定時(shí)器1:模式2,定時(shí)器2:模式1
TL1=253; TH1=253; // 9600波特率
TR1=1; //啟動(dòng)定時(shí)器1
SCON=0x50; //串口:模式1
TL0=0x00; TH0=0x0A6; //定時(shí)器0定時(shí)0.025秒
TR0=1; //啟動(dòng)定時(shí)器0
countdown=40; //1秒=0.025*40
P1_4=1; //釋放繼電器RY1、RY2
TX_buf[0]=0x7E; TX_len=3;
RX_num=0; RX_len=3;
while(1) ;
}
三、 山下控制板
山下控制板的電路圖如下所示,所包括的主要元件有單片機(jī)芯片89C2051,電平轉(zhuǎn)換芯片MAX232,7805穩(wěn)壓芯片。芯片MAX232的功能是把單片機(jī)串口的TTL電平轉(zhuǎn)換成MODEM的RS-232電平,使單片機(jī)能通過(guò)MODEM收發(fā)數(shù)據(jù)。需要對(duì)山上設(shè)備進(jìn)行開(kāi)關(guān)電操作時(shí),先把連接在2051單片機(jī)P1_7腳的斷電開(kāi)關(guān)撥到“開(kāi)”或“關(guān)”的位置,然后連續(xù)按下K1按鍵,直到L1、L2、L3三個(gè)操作指示燈全亮,接著按一下K2按鍵,L1、L2、L3指示燈全滅,此時(shí)2051單片機(jī)檢查P1_7腳的電平,如果是低電平,則向山頂控制板發(fā)斷電指令,如果是高電平,則向山頂控制板發(fā)加電指令。K1、K2的其它按鍵組合均不使單片機(jī)發(fā)送加斷電指令。這里采取斷電開(kāi)關(guān)與按鍵相結(jié)合的控制方式,目的是為了防止意外的開(kāi)關(guān)操作,提高安全性。MODEM通信正常的情況下,山下控制板每秒鐘收到一次山頂控制板發(fā)來(lái)的加斷電狀態(tài)報(bào)告。當(dāng)接收到狀態(tài)報(bào)告后,經(jīng)單片機(jī)分析,如果是斷電狀態(tài),則P1_5腳輸出低電平,點(diǎn)亮斷電指示燈,P1_3腳輸出高低脈沖,驅(qū)動(dòng)蜂鳴器告警提示;如果是加電狀態(tài),斷電指示燈滅,蜂鳴器靜音。如果連續(xù)3秒鐘收不到山頂控制板的狀態(tài)報(bào)告,斷電指示燈將作秒閃、蜂鳴器告警,提示操作人員檢查MODEM線路是否正常。
山下控制板的程序如下:
#include "atmelAT89X51.H"
#define SYN 0x7E //山頂控制板發(fā)來(lái)數(shù)據(jù)幀的同步字符
char countdown; //時(shí)鐘計(jì)數(shù)
char TTL; //通信中斷的時(shí)間門(mén)坎值,設(shè)置為3秒
bit link_error; //通信中斷標(biāo)志
bit power_on; //山上設(shè)備是否加電的標(biāo)志
bit km; //按鍵消抖動(dòng)標(biāo)志
bit kp; //按鍵操作已處理標(biāo)志
char TTW; //發(fā)送指令前的時(shí)間計(jì)數(shù)
char TX_buf[3]; //發(fā)送緩沖區(qū)
char TX_len; //發(fā)送指令長(zhǎng)度
char TX_num; //當(dāng)前發(fā)送的字符序號(hào)
char RX_buf[3]; //接收緩沖區(qū)
char RX_len; //接收指令長(zhǎng)度
char RX_num; //當(dāng)前接收的字符序號(hào)
char CRC(char *buf,char len) //校驗(yàn)碼生成函數(shù)
{char i,temp;
temp=0;
for(i=0;i<len;i++) temp=temp^buf[i];
return(temp);
}
void timer0_int() interrupt 1 //定時(shí)器0的中斷服務(wù)函數(shù)
{ bit key1,key2;
TL0=0x00; TH0=0x0A6;
countdown--;
if(countdown==0 || countdown==20)
{ P1_6=!P1_6; //CPU運(yùn)行指示燈秒閃
if(link_error)
P1_5=!P1_5; //通信中斷,斷電指示燈秒閃
else
{ if(power_on) P1_5=1; //設(shè)備加電,斷電指示燈滅
else P1_5=0; //設(shè)備關(guān)電,斷電指示燈亮
}
}
if(power_on && !link_error) //當(dāng)設(shè)備加電且通信正常
P1_3=0; //關(guān)閉蜂鳴器
else //當(dāng)設(shè)備斷電或通信中斷
{ if(countdown==0) P1_3=0; //蜂鳴器告警
if(countdown==5) P1_3=1;
if(countdown==10) P1_3=0;
if(countdown==15) P1_3=1;
}
key1=P3_4; key2=P3_5;
if(key1==1 && key2==1) { km=0;kp=0; } //兩個(gè)按鍵均沒(méi)有按下
else
{ if(km==0) km=1; //設(shè)消抖動(dòng)標(biāo)志
else
{ if(kp==0)
{ kp=1;
if(key1==0) //按鍵K1被按下
TTW=(TTW+1)%4; //計(jì)算K1連續(xù)按下的次數(shù)
if(key2==0) //按鍵K2被按下
{ if(TTW==3) //如果K1已被連續(xù)按了三次
{ if(P1_7) TX_buf[1]=0x13; //發(fā)加電指令
else TX_buf[1]=0x31; //發(fā)關(guān)電指令
TX_buf[2]=CRC(TX_buf,2);
TX_num=0; SBUF=TX_buf[0];
}
TTW=0; //不管K1已按下幾次,K2按下后復(fù)位TTW計(jì)數(shù)器
}
}
}
}
if(countdown!=0) return;
countdown=40;
if(TTL==0) link_error=1; //TTL減到0,表示通信中斷
else TTL--; //每隔1秒對(duì)TTL作減1操作
}
void serial_int() interrupt 4 //串口中斷服務(wù)程序
{ if(TI)
{ TI=0; TX_num++;
if(TX_num<TX_len) SBUF=TX_buf[TX_num];
}
else
{ RI=0; RX_buf[RX_num]=SBUF;
if(RX_num==0 && RX_buf[RX_num]!=SYN)
return; //在接收到的數(shù)據(jù)中搜索同步字符
RX_num++;
if(RX_num==RX_len) //接收到一完成指令
{ RX_num=0;
if(RX_buf[RX_len-1]==CRC(RX_buf,RX_len-1)) //檢查校驗(yàn)
{ if(RX_buf[1]==0x13) power_on=1; //加電狀態(tài)
if(RX_buf[1]==0x31) power_on=0; //斷電狀態(tài)
TTL=3; link_error=0; //通信正常,重置TTL值
}
}
}
}
void main()
{ IE=0x92;
TMOD=0x21; //定時(shí)器1:模式2,定時(shí)器0:模式1
TL1=253; TH1=253; //9600波特率
TR1=1; //啟動(dòng)定時(shí)器1
SCON=0x50; //串口:模式1
TL0=0x00; TH0=0x0A6; //定時(shí)器0定時(shí)0.025秒
TR0=1; //啟動(dòng)定時(shí)器0
countdown=40; //1秒=0.025秒*40
TTL=3; //連續(xù)3秒收不到報(bào)告,表示通信中斷
TTW=0;
km=0; kp=0;
link_error=1; power_on=1;
TX_buf[0]='Z'; TX_len=3;
RX_num=0; RX_len=3;
while(1)
{ if(TTW==0) { P3_7=1; P1_0=1; P1_1=1; }
if(TTW==1) P3_7=0;
if(TTW==2) P1_0=0;
if(TTW==3) P1_1=0;
}
}
四、MODEM通信線制作
單片機(jī)2051與MODEM之間的串口通信電纜只用RX、TX、GND三根線,其他的握手信號(hào)均沒(méi)有使用,但在制作MODEM一端的接頭時(shí)應(yīng)要按下圖制作: