面试题求助,C语言请进。。
各位,这个是我妹妹的面试题,人家要求是写出程序的详细功能,然后提出建议。各位请帮忙看看。我妹妹理解的是这样的:。
本程序功能:检测信号,当检测时间超过25s时,表示有系统故障,将p2拉高,延时12*42s。当检测到上升沿到来时,LED灯显示,且读取p2口对应12个地址状态(数组中定义)。
谢谢大家了
#include "reg52.H"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit P0_0 = 0x80;
sbit P0_1 = 0x81;
sbit P0_2 = 0x82;
sbit P0_3 = 0x83;
sbit P0_4 = 0x84;
sbit P0_5 = 0x85;
sbit P1_5 = 0x95;
sbit P2_7 = 0xA7;
sbit IntSignal=0xB5;
sfr WDT_CONTR=0xe1;
sbit CS=0xe9;
uchar Addr;
uint msCount;
uchar SignalTimeOut;
uchar SignalTime;
uint ProcLEDTime;
uchar State_p2;
bit erro=0;
bit StateTime=0;
bit RSState=0;
uint ClockMs,ClockS;
uint TempClockS;
uchar S_State,M_State,E_State;
uchar Move_State;
uchar State;
bit Erro_ri=0;
bit SignalState;
bit rise;
bit ProcStop;
uchar code StateTab[12]={0xbe,0xde,0xee,0xf6,
0xbd,0xdd,0xed,0xf5,
0xbb,0xdb,0xeb,0xf3,};
/*__________________________
读取P2口状态
----------------------------*/
void Statecode(uchar State_code)
{
switch (State_code)
{ case 0xbe: State_p2=0; break;
case 0xde: State_p2=1; break;
case 0xee: State_p2=2; break;
case 0xf6: State_p2=3; break;
case 0xbd: State_p2=4; break;
case 0xdd: State_p2=5; break;
case 0xed: State_p2=6; break;
case 0xf5: State_p2=7; break;
case 0xbb: State_p2=8; break;
case 0xdb: State_p2=9; break;
case 0xeb: State_p2=10; break;
case 0xf3: State_p2=11; break;
default: break;
}
}
void mDelay(uint Dat)
{
uint j;
for (;Dat>0;Dat--)
{for (j=42;j>0;j--);WDT_CONTR=0x38;}
}
void Delay10m() //10分钟延时,600秒
{
ClockMs=0;
ClockS=0;
while(ClockS<600) ;
}
/*——————————————————————————————————
故障状态
------------------------------------*/
void Error()
{
ET0=0;
P2=0xff;
mDelay(12);
P0_0=1;
erro=1;
P0_4=1;
P0_5=0;
while(1)
{
P0_3=~P0_3;
mDelay(500);
}
}
/*______________________
P2_7
-----------------------*/
void SignalCheck()
{
if(SignalTimeOut>25) Error(); //20ms内监测
else erro=0;
rise=0;
if(SignalState!=P2_7)
{
SignalState=P2_7;
rise=SignalState;
SignalTimeOut=0;
}
if(rise) SignalTime+=1;
if(P0_4&&(SignalTime==100)){P0_4=0;SignalTime=0;}
if((!P0_4)&&(SignalTime==50)){P0_4=1;SignalTime=0;}
}
/*_________________________________
P0_3
---------------------------------*/
void ProcLED()
{
if(ProcStop) {P0_3=1;return;}
ProcLEDTime+=1;
if(ProcLEDTime==2000) {P0_3=~P0_3;ProcLEDTime=0;}
}
void Timer0() interrupt 1 using 0
{
TL0=0x9a; //
TH0=0xfe; //
SignalTimeOut+=1;
msCount+=1;
ClockMs+=1;
if(ClockMs==1000){ClockMs=0;ClockS+=1;}
SignalCheck(); //检测上升沿
ProcLED();
WDT_CONTR=0x38;
}
/*________________________________
--------------------------------*/
void StateProc(uchar delay)
{
uchar i;
if(delay)
{
for(i=5;i>0;i--) { msCount=0;while(msCount<60000);} //5分钟延时
}
else
{
msCount=0;
while(msCount<20000); //20秒延时
}
while(!rise);//检上升沿到来
msCount=0;
while(msCount<1);//延1ms
P2=0xff;//置高
msCount=0;
while(msCount<10);//2008-03-04修10ms
/*while(!rise);//检上升沿到*/
P2=StateTab[State];//执行
}
void IntProc()
{
if(IntSignal)return;
E_State= P1>>5;
ProcStop=0;
while(!(IntSignal&&(State==M_State)))
{
if(IntSignal)
{
if(State<M_State)
{State+=1;StateProc(0);}
}
else
{
if(State==E_State) while(!IntSignal);
else {State-=1;StateProc(0);}
}
}
ProcStop=1;
}
/*-------------------------------------
等待延时
-------------------------------------*/
void mDelay0(register uchar n)
{
for(n;n>1;n--) WDT_CONTR=0x38;
}
/*-------------------------------
发送地址
------------------------------*/
void SendsAddr()
{
WDT_CONTR=0x38;
TB8=0;
CS=0;
mDelay0(10);
P0_1=0;
SBUF=Addr;
while(!TI);
TI=0;
mDelay0(15);
SM2=0;
CS=1;
mDelay0(5);
}
/*------------------------------
发送数据
-----------------------------*/
void SendsData()
{
uchar temp;
WDT_CONTR=0x38;
TB8=0;
CS=0;
mDelay0(10);
temp=P2;
Statecode(temp);
if(!erro) SBUF=State_p2;
else SBUF=13;
while(!TI);
TI=0;
mDelay0(15);
SM2=1;
CS=1;
mDelay0(5);
}
/*-------------------------------
执行P0口命令
--------------------------------*/
void D_Move()
{
mDelay(1000);
WDT_CONTR=0x38;
if(State>Move_State)
{ ProcStop=0;
Erro_ri=0;
do
{
State-=1;
StateProc(0);
}
while(State>Move_State);
ProcStop=1;
}
else if(State<Move_State)
{
Erro_ri=0;
ProcStop=0;
do
{
State+=1;
StateProc(0);
}while(State<Move_State);
ProcStop=1;
}
else { Erro_ri=0; StateProc(0); }
mDelay(1000);
}
/*--------------------------------
串口中断
---------------------------------*/
void Uart() interrupt 4 using 1
{
if(RI==1)
{ uchar temp;
uchar temp0;
uchar Sbuftemp;
RI=0;
Sbuftemp=SBUF;
Erro_ri=1;
mDelay0(15);
if(SM2==0)
{
temp=Sbuftemp&0x0f;
if(temp>11) { RSState=0; Move_State=11; }
else
{ Addr=P1&0xc0;
temp0=Sbuftemp&0xc0;
if((temp0==Addr)||(temp0==0x00)) { RSState=1; Move_State=temp; }
}
SendsData();
}
else
{
Addr=P1&0xc0;
if(Sbuftemp==Addr) SendsAddr();
else
{
SM2=1;
P0_1=1;
CS=1;
}
}
}
else TI=0;
}
void main()
{
P2=0xff;P0=0xff;P1=0xff;P3=0xff;
mDelay(1000); //启动延迟时间
SCON=0x90;
PCON=0x00;
SM2=1;
TH0=0xfe; //
TL0=0xa2; //晶振4.194304 MHz 1ms定时
TMOD=0x01; //
TR0=1;
IP=0x10;
EA=1;
ES=1;
ET0=1;
Addr=P1&0xc0;
SignalState=P2_7;
WDT_CONTR=0x38;
S_State=7; //启动端口
State=S_State;
while(!rise);
P0_0=0;
ProcStop=0;
P2=StateTab[State];
do
{
Erro_ri=0;
State+=1;
StateProc(0);
}
while(State<11);
ProcStop=1;
Delay10m(); //10分钟
/*mDelay(2000);*/
M_State=11-((P1>>3)&0x3);
ProcStop=0;
while(State>M_State)
{
Erro_ri=0;
State-=1;
StateProc(0);
}
ProcStop=1;
retu: mDelay(5000);
while(Erro_ri&RSState) D_Move();
ClockMs=0;
ClockS=0;
while(ClockS<14400) //延时4小时,14400秒
{
if(Erro_ri&RSState) goto retu;
if(!IntSignal)
{
mDelay(1000);
if(!IntSignal)
{
TempClockS=ClockS;
IntProc();
ClockS=TempClockS;
}
}
}
Erro_ri=0;
S_State=P1&0x07;
if(State>S_State)
{
ProcStop=0;
do
{
if(Erro_ri&RSState) goto retu;
State-=1;
StateProc(1);
}
while(State>S_State);
ProcStop=1;
}
else if(State<S_State)
{
ProcStop=0;
do
{
if(Erro_ri&RSState) goto retu;
State+=1;
StateProc(1);
}
while(State<S_State);
ProcStop=1;
}
else { if(Erro_ri&RSState) goto retu; StateProc(1); }
while(1) if(Erro_ri&RSState) goto retu;
}