#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define TIME_COUNT 11//22.1184MHz晶振10us定時中斷
#define FOSC 11059200L//22118400L
sfr P2M1=0x95;
sfr P2M0=0x96;
sbit sb=P3^2;//開門信號
sbit sq1=P3^3;//開門限位
sbit sq2=P3^4;//關門限位
sbit s4=P3^5;//關門防夾
sbit x0=P1^0; //延時關門時間選擇
sbit x1=P1^1;
sbit x2=P1^2;
sbit x3=P1^3;
sbit x4=P1^4;
sbit x5=P1^5;
sbit x6=P1^6;
sbit x7=P1^7;//延時關門時間選擇
sbit kai=P2^1;//開門(正轉)
sbit guan=P2^0;//關門(反轉)
uchar aa[3],bb; //串口收到數據寄存器
uchar z0,z1,z2,z3,z4,z5,z6,z7,z8,z9,z10; //時間繼電器
uint t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10; //時間繼電器
uint num1,n,n1,n2,n3,n4,n5,n6,n7,n8;//延時關門設置
uchar a=0,m;//門當前狀態
void delayms(uint xms);
void kaimen();
void guanmen();
void delayms(uint xms) //延時函數
{
uint i,j;
for(i=xms;i>0;i--)
for(j=330;j>0;j--);
}
void init()
{
P2=0; P2M0=0xff;P2M1=0;
TMOD=0x01;
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
EA=1;ET0=1;TR0=1;
if(x0==0){delayms(5);if(x0==0)n1=20;} if(x0==1){delayms(5);if(x0==1)n1=0;}
if(x1==0){delayms(5);if(x1==0)n2=40;} if(x1==1){delayms(5);if(x1==1)n2=0;}
if(x2==0){delayms(5);if(x2==0)n3=60;} if(x2==1){delayms(5);if(x2==1)n3=0;}
if(x3==0){delayms(5);if(x3==0)n4=100;} if(x3==1){delayms(5);if(x3==1)n4=0;}
if(x4==0){delayms(5);if(x4==0)n5=160;} if(x4==1){delayms(5);if(x4==1)n5=0;}
if(x5==0){delayms(5);if(x5==0)n6=200;}if(x5==1){delayms(5);if(x5==1)n6=0;}
if(x6==0){delayms(5);if(x6==0)n7=300;}if(x6==1){delayms(5);if(x6==1)n7=0;}
if(x7==0){delayms(5);if(x7==0)n8=400;}if(x7==1){delayms(5);if(x7==1)n8=0;}
n=n1+n2+n3+n4+n5+n6+n7+n8+1;
// while(!sb||!s4);guanmen();
}
void USART_Init(uint BAUD)//初始化串行口和波特率發生器
{
SCON =0x50; //選擇串口工作方式1,打開接收允許
TMOD=0x21; //定時器1工作在方式2,定時器0工作在方式1
TH1 =TL1 = (256 - (FOSC/12/32/BAUD)); //設置波特率重裝值
TR1 =1; //啟動定時器T1
ES=1; //允許串行口中斷
EA=1;
}
void kaimen() //開門函數
{
t0=0; //計時器清零
z0=1; //打開計時器
kai=1; //開門
while(1)
{
if(a==3&&z4==0){SBUF=0x3b;while(!TI);SBUF=P0;while(!TI);SBUF=0xe7;while(!TI);a=3;z4=1;} //正在開門信號發出
if(sq1==0){delayms(5);if(sq1==0){kai=z0=t0=0;m=1;break;}} //開門到位
if(t0>=300) //計時保護30秒
{
kai=0;guan=0;while(!sq2);while(1)
{
if(sq1==0||sq2==0||t0>3000){delayms(5);if(sq1==0||sq2==0||t0>3000){z0=t0=0;break;}}
}break;
}
}
z2=1;
while(!sb||z2||!s4)
{
if(a==3&&z3==0){SBUF=0x72;while(!TI);SBUF=P0;while(!TI);SBUF=0x69;while(!TI);z3=1;} //開門完成信號發出
if(a==1){SBUF=0x72;while(!TI);SBUF=P0;while(!TI);SBUF=0x69;while(!TI);a=0;} //門開到位信號發出
if(a==2){z3=t3=0;} //AGV收到開門完成信號
if(t3>50)t3=z3=0;//AGV沒有收到開門完成信號 重復發送開門信號
if(t2>=n)z2=t2=0;//延時關門
}
if(a==4){SBUF=0x75;while(!TI);SBUF=P0;while(!TI);SBUF=0x36;while(!TI);a=0;}//收到關門信號發出
m=a=0;
guanmen();
}
void guanmen() //關門函數
{
t0=0;z0=1;guan=1;
while(1)
{
if(a==4){SBUF=0x75;while(!TI);SBUF=P0;while(!TI);SBUF=0x36;while(!TI);a=0;}//收到關門信號發出
if(sq2==0){delayms(5);if(sq2==0){guan=t0=z0=0;break;}} //關門到位
if(t0==300) //計時保護
{
kai=0;guan=0;while(!sq1);while(1)
{
if(t0>=3000){num1++;if(num1==4){while(sq2);num1=0;}t0=z0=0;break;}
if(sq1==0||sq2==0){delayms(5);if(sq1==0||sq2==0){t0=z0=0;break;}}
}break;
}
if(sb==0||s4==0){delayms(5);if(sb==0||s4==0){guan=0;delayms(2000);kaimen();}}//開門信號
}
}
void main()
{
init();
USART_Init(9600);
while(1)
{
if(sb==0){delayms(5);if(sb==0)kaimen();}//感應有人
if(sq2==1){delayms(5);if(sq2==1)guanmen(); }//沒關好門
if(a==4){SBUF=0x75;while(!TI);SBUF=P0;while(!TI);SBUF=0x36;while(!TI);a=0;}//收到關門信號發出
}
}
void T0_time() interrupt 1
{
TH0=(65536-45872)/256; //
TL0=(65536-45872)%256;
if(z0==1) t0++; //時間繼電器0 開關門卡死保護
if(z1==1) t1++; //時間繼電器1 收信號間隔清零時間
if(z2==1) t2++; //時間繼電器2 延時關門
if(z3==1) t3++; //時間繼電器3 發出信號沒回應延時再次發送
if(z4==1) t4++; //時間繼電器4
if(z5==1) t5++; //時間繼電器5
if(z6==1) t6++; //時間繼電器6
if(z7==1) t7++; //時間繼電器7
if(z8==1) t8++; //時間繼電器8
if(z9==1) t9++; //時間繼電器9
if(z10==1) t10++; //時間繼電器10
if(t1>=2)z1=t1=bb=0;//間隔超時清零
// if(t10==0)guan=0;if(t10==5)guan=1;if(t10>10)t10=guan=0;
}
void USART(void) interrupt 4
{
if(RI)
{
aa[bb]=SBUF;
RI=0;
bb++;
z1=1;
t1=0;
if(bb>=3)
{
bb=z1=t1=0;
if(aa[0]==0x1e&&aa[1]==P0&&aa[2]==0x37) //開門信號
{
sb=0;
if(m==0){z4=0;a=3;} //正在開門信號發出
if(m==1){a=1;} //門開到位信號發出
}
if(aa[0]==0x37&&aa[1]==P0&&aa[2]==0x6e) //AGV收到開門信號
{
sb=0;a=2;
}
if(aa[0]==0x69&&aa[1]==P0&&aa[2]==0x17) //關門信號
{
a=4;//關門信號發出
sb=1;
}
}
}
if(TI)
TI=0;
}
|