#include<reg52.h>
#include<intrins.h>
sbit P3_7=P0^6; // 点动按钮
sbit P3_6=P0^5; // 单梭按钮
sbit P3_5=P0^4; // 启动按钮
sbit P3_4=P0^3; // 停止按钮
sbit P3_3=P2^6; // 经停信号输入
sbit P3_2=P2^7; // 纬停信号输入
sbit P3_1=P3^1; // “加”指示灯
sbit P3_0=P3^0; // “减”指示灯
//sbit P2_7=P2^7; //
//sbit P2_6=P2^6; //
sbit P2_5=P2^5; // “减”按钮
sbit P2_4=P2^4; // “加”按钮
//sbit P2_4=P2^4; // 储纬继电器
sbit P2_3=P1^2 ; // 保护输出,至指示灯, 继电器
sbit P2_2=P3^7 ; // 高压输出
sbit P2_1=P3^6; // 离合输出
sbit P2_0=P2^0; // 制动输出
sbit P1_7=P0^7; // 储纬停信号输入
sbit P1_6=P0^2; // H3信号输入
sbit P1_5=P0^1; // H2信号输入
sbit P1_4=P0^0; // H1信号输入
sbit P1_3=P3^4; // DIP2
sbit P1_2=P3^5; // DIP3
sbit P1_1=P3^3; // DIP4
// sbit P1_0=P1^0; //
// sbit P0_7=P0^7; //
sbit P0_6=P3^2; // 过载保护输入
sbit P0_5=P2^1; // 保护输入,高压检测
sbit P0_4=P2^2; // 保护输入,离合检测
sbit P0_3=P2^3; // 保护输入,制动检测
sbit P0_2=P1^3; // 储纬停输出,至指示灯,继电器。
sbit P0_1=P1^0; // 纬停输出
sbit P0_0=P1^1; // 经停输出
#define uchar unsigned char
# define uint unsigned int //注意 无冒号
static unsigned char flag,flag1,flag2,flag3,flag4,flag5,flag6,flag7;
bit testflag,testflag1,testflag2,testflag3;
static unsigned char temp=0,temp1=0,temp2=0,temp3=0,tag=0,tag1=0,tag2=0,tag3=0,count=0;
static unsigned char tag4=0,tag5=0,tag6=0,tag7=0;
static unsigned char temp4=0,temp5=0,temp6=0,temp7=0,temp8=0,temp9=0, xx=0,count1=0,enable=0,mean=0;
static unsigned char x,x1,x2,x3;
static unsigned int i,j,k,i1,j1,k1;
sfr T2MOD = 0xC9;
void delay(uchar ms);
//sfr WDT_CONTR=0xe1; //看门狗地址
sfr ISP_DATA = 0xE2; /* Flash Data Register */
sfr ISP_ADDRH = 0xE3; /* flash address high */
sfr ISP_ADDRL = 0xE4; /* flash address low */
sfr ISP_CMD = 0xE5; /* flash command register */
sfr ISP_TRIG = 0xE6; /* flash command trigger */
sfr ISP_CONTR = 0xE7; /* isp/iap control register */
#define ISP_IAP_BYTE_READ 1; /* 读字节 */
#define ISP_IAP_BYTE_PROGRAM 2; /* 字节编程 */
#define ISP_IAP_SECTOR_ERASE 3; /* 扇区擦除 */
#define ISP_IAP_ENABLE 0x81; /* 系统工作时钟<12M,对ISP_CONTR寄存器设置此值 ,0x81*/
unsigned char byte_read(unsigned int addr);
void byte_write(unsigned int addr,unsigned char program_data);
void Sector_Erase(unsigned int addr);
void IAP_Disable();
unsigned int eeprom_address;unsigned char read_eeprom;
unsigned char value_buf[22];
void main (void)
{
P2_0=0; xx=0;
TMOD=0x11;
EA=1;ET0=1;ET1=1;
TH0=(65536-10000)/256;TL0=(65536-10000)%256; TR0=0;
TH1=(65536-10000)/256;TL1=(65536-10000)%256; TR1=0;
ET2=1; //T2中断允许
T2MOD=0x00; //如果T2MOD=0X02,则从P1_0输出
T2CON=0x00;
//CP_RL2=1;EXEN2=1;
TH2=(65536-50000)/256;
TL2=(65536-50000)%256;
RCAP2H=(65536-50000)/256; //重装载计数器赋初值
RCAP2L=(65536-50000)%256;
read_eeprom=byte_read(0x2000);
x=read_eeprom;
if (x<5) x=5;
if(x>25) x=25;
x1=byte_read(0x2200);
if (x1<35) x1=35;
if(x1>45) x1=45;
while(1)
{
if ((P3_7==1) &&(temp1==1) || (P3_6==1)&&(temp1==1) ) temp2=1; // temp2点动单梭终止运行标志
while (temp2==1)
{
//if (!((P1_6==1) && (P1_4==1)&&(P1_5==0)) ) continue;
// else
if((P1_6==1)&&(P1_5==0)&&(P1_4==1))
{P2_1=1;P2_0=0;temp=0;temp1=0;temp2=0;enable=0;}
}
if ((P3_3==1)&&(temp1==1) &&(xx==0)) {temp3=1;P0_0=0;} // temp3经停标志
while((temp3==1) && (temp1==1)&&(xx==0))
{
// if(!((P1_6==1) && (P1_4==1)&&(P1_5==0))) continue;
// else
if((P1_6==1)&&(P1_5==0)&&(P1_4==1))
{P2_1=1;temp1=0;P2_0=0; P0_0=0;enable=0;temp3=0;}
}
if ((P1_7==1)&&(temp1==1) &&(xx==0) ) {temp4=1;P0_2=0;} //temp4储纬停标志
while((temp4==1) &&(temp1==1)&&(xx==0))
{
//if(!((P1_6==1) && (P1_4==1)&&(P1_5==0)) ) continue;
// else
if((P1_6==1)&&(P1_5==0)&&(P1_4==1))
{P2_1=1;temp1=0;P0_2=0;P2_0=0;enable=0;}
}
if ((temp4==1) && (temp1==0) && (P3_4==1)) {P0_2=1; temp4=0;} //解除储纬停标志
if ((P3_2==0)&&(temp1==1) && (enable==1)&&(xx==0)) //纬停负输入
{
delay(10);
if ((temp1==1) && (enable==1)&&(P3_2==0) &&(xx==0))
{
//count1数字滤波计数 略
{
}
if (mean==5) //mean 采样值 之和 略
{ //enable=1 纬停允许
while ((temp1==1) && (enable==1)&&(P3_2==0)&&(xx==0)&&(P0_5==0)&&(P0_3==0)&&(P0_6==1))
{
/*if(!((P1_6==1) && (P1_5==1))) continue; //断纬时 仍可保护
else
{delay(2); P2_1=1;P2_0=0;temp1=0;temp5=1;enable=0;P0_1=0;} */ //temp5 纬停标志
if((P1_6==1)&&(P1_4==0)&&(P1_5==1)&&(P3_2==0)) //传感器正输入
flag=1; //flag 断纬,传感器后沿停机记忆
while ((flag==1)&&(P3_2==0)&&(xx==0)&&(P0_5==0)&&(P0_3==0)&&(P0_6==1) )
{
if ((P1_6==0)&&(P1_5==0))
{temp5=1;flag=0;enable=0;} //temp5 纬停标志
}
}
}
}
}
if(P3_2==1)
{
flag=0; //松开按钮 flag=0;
for (count1=0;count1<5;count1++) //count1数字滤波计数
{
value_buf[count1]=0;
}
mean=0;
}
if (temp5==1)
{
delay(2); P2_1=1;delay(1);P2_0=0;temp1=0;enable=0;P0_1=0;_nop_();
for (count1=0;count1<5;count1++)
{
value_buf[count1]=0;
}
mean=0;
temp5=0;
}
if ((P3_6==1) && (temp1==0) &&(temp==0)&&(temp4==0)&&(xx==0)) //单梭 ,temp 单梭标志
{
P2_0=1;
P2_1=0;
temp=1;
}
while (temp==1)
{
//if (!(( P1_5==1)&&(P1_6==0)&&(P1_4==0)|| (P3_4==1)) ) continue; //P1_5 ,H2信号 单梭停止
// else
if((P1_6==0)&&(P1_5==1)&&(P1_4==0) ||(P3_4==1))
{
P2_1=1;
temp=0;
P2_0=0;
}
}
if ((P3_5==1) && (temp4==0)&&(P3_4==0)&&(xx==0)) //无储纬停,无保护 ,启动
{P2_0=1;P2_1=0;_nop_(); temp=0;temp1=1;temp3=0;temp5=0;_nop_();P0_0=1;P0_1=1;}
//temp1 启动标志 ,temp8==1,开机瞬间纬停无效
//while ( (temp3==0)&&(temp4==0)&& (temp5==0)&&(xx==0)&&(temp1==1))
if ((temp3==0)&&(temp4==0)&& (temp5==0)&&(xx==0)) //停止
{
if (P3_4==1)
{ P2_1=1; P2_0=0;_nop_();temp=0;temp1=0;enable=0;}
}
if ((temp==0) && (temp1==0) &&(temp4==0)&& (P3_7==1) &&(xx==0) && (tag==0)) //tag 切断点动动作按钮
{
//delay(1);
temp9=1; //temp9 点动状态运行中
P2_0=1; tag=1; tag1=0; count=1; //开机瞬间无高压,count==0;
delay(1); //间隔
P2_1=0; P2_2=0;
delay(20);P2_2=1; //高压1时间
delay(x1); //离合时间
if (P3_7==0) //松开点动按钮
{
P2_1=1;
}
}
if ((P3_7==0)&&(temp==0) && (temp1==0) &&(temp4==0)&&(xx==0) ) //松开点动按钮
{
// delay(1);
tag=0;
P2_1=1;delay(1); //间隔
P2_0=0; //delay(1);
}
/* if ((P3_7==0)&&(P2_1==1)&&(temp==0)&&(temp1==0)&&(temp4==0)&&(tag1==0)&&(xx==0))
{
tag=0;P2_1=1;_nop_();P2_0=0;
tag1=1; //tag1 切断点动制动
if (count==1) P2_2=0; //点动制动后,瞬间高压
delay(20); //高压2时间
P2_2=1; _nop_(); temp9=0; //temp9 点动状态标志
} */
if ((P2_0==0) && (P2_1==1) &&(temp==0)&& (temp1==0)&&(temp4==0) &&(tag1==0)&&(tag==0))
{
tag1=1;tag=0; //tag1 切断点动制动
if (count==1) P2_2=0; //点动制动后,瞬间高压
delay(20); //高压2时间
P2_2=1; delay(20); _nop_(); temp9=0;
}
if ((tag==1) && (tag1==1)) tag=0; //防止互锁
if ((P0_3==1) &&(P0_4==1))
{
//delay(200); //延时时间不能太长
delay(10);
if ((P0_3==1) &&(P0_4==1))
//{ temp6=1;xx=1;P2_1=1;P2_0=1;P2_2=1;P2_3=0; } //temp6 逻辑保护标志
TR1=1;
// else {TR1=0;k=0;}
}
if ((P0_5==1)&&(P3_7==0)) TR1=1; //无点动,高压触发保护定时器
if(!((P0_3==1)&&(P0_4==1))&&(P0_5==0)) {TR1=0;k=0;}
if (P0_6==0) //过载信号负输入
{
delay(200);
if (P0_6==0)
{temp7=1;xx=1;P2_1=1;P2_0=1;P2_2=1;P2_3=0; } //temp7 过载保护
}
if ((temp6==1) ||(temp7==1)) {xx=1;P2_1=1;P2_0=1;P2_2=1;P2_3=0; } //保护
if((P1_3==0)&&(P1_2==1)&&(P1_1==0)) // DIP2 DIP4 ON DIP3 OFF 纬停采样调整
{
if(P3_4==1) //停止按钮按下
{
if ((P2_4==0) &&(tag2==0) ) // tag2切断 加按钮 最多按18次
{
if(x<=24) {x+=1; P3_1=0;}
tag4=0;tag2=1;delay(10);P3_1=1;
}
if (P2_4==1) tag2=0;
if ((P2_5==0) &&(tag3==0)) //tag3切断 减按钮 最多按18次
{
if(x>=6) {x-=1; P3_0=0;}
tag4=0;tag3=1;delay(10);P3_0=1;
}
if (P2_5==1) tag3=0;
}
if((P3_4==0)&&(tag4==0)) //tag4==0 写允许 停止按钮松开
{
Sector_Erase(0x2000); _nop_();byte_write( 0x2000, x); _nop_();_nop_();tag4=1;
}
}
if((P1_3==0)&&(P1_2==0)&&(P1_1==1)) // DIP2 DIP3 ON DIP4 OFF 点动距离调整
{
if(P3_4==1) //停止按钮按下
{
if ((P2_4==0) &&(tag2==0) ) // tag2切断 加按钮 最多按10次
{
if(x1<=44) {x1+=1; P3_1=0;}
tag4=0;tag2=1;delay(10);P3_1=1;
}
if (P2_4==1) tag2=0;
if ((P2_5==0) &&(tag3==0)) //tag3切断 减按钮 最多按10次
{
if(x1>=36) {x1-=1; P3_0=0;}
tag4=0;tag3=1;delay(10);P3_0=1;
}
if (P2_5==1) tag3=0;
}
if((P3_4==0)&&(tag4==0)) //tag4==0 写允许 停止按钮松开
{
Sector_Erase(0x2200); _nop_();byte_write( 0x2200, x1); _nop_();_nop_();tag4=1;
}
}
//if (temp1==1) {delay(10); enable=1;} // 开机瞬间纬停无效
if (P3_5==1) TR2=1; //按钮输入正
if ((temp1==0)&&(P3_5==0)) {enable=0; i1=0;TR2=0;}
if (P2_0==0) //制动后 所有状态复位 ,temp4除外
{ //count1数字滤波计数
for (count1=0;count1<5;count1++)
{
value_buf[count1]=0;
}
mean=0;
enable=0;
temp=0;temp1=0;temp2=0;temp3=0;temp5=0;
}
}
}
void int_1(void) interrupt 1
{
TR0=0;
TH0=(65536-10000)/256;TL0=(65536-10000)%256;
}
void int_3(void) interrupt 3 //保护定时器
{
k++;
if(k>=100)
{
xx=1;P2_1=1;P2_0=1;P2_2=1;P2_3=0; _nop_(); P2_0=1;
TR1=0; k=0; temp6=1;
}
TH1=(65536-10000)/256;TL1=(65536-10000)%256;
}
void timer2() interrupt 5
{
i1++; TF2=0; //T2中断 溢出标志,必须清除
if (i1>=10) //1S, 0.5s
{
TR2=0; i1=0; enable=1; // 定时时间到标志 ,纬停允许
}
// TH2=(65536-50000)/256;
//TL2=(65536-50000)%256;
}
unsigned char byte_read(unsigned int addr)
{
unsigned char ii;
ISP_ADDRH = (addr>>8);
ISP_ADDRL = (addr&0x00ff);
ISP_CONTR = ISP_IAP_ENABLE; //0x81
ISP_CMD = ISP_IAP_BYTE_READ; //1
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
_nop_();
ii = ISP_DATA;
ISP_CONTR = 0x00;
ISP_CMD = 0x00;
ISP_TRIG = 0x00;
return ii;
}
void byte_write(unsigned int addr,unsigned char program_data)
{
ISP_DATA = program_data;
ISP_ADDRH = (addr>>8);
ISP_ADDRL = (addr&0x00ff);
ISP_CONTR = ISP_IAP_ENABLE; // 0x81
ISP_CMD = ISP_IAP_BYTE_PROGRAM; // 2
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
ISP_CONTR = 0x00;
ISP_CMD = 0x00;
ISP_TRIG = 0x00;
}
// void IAP_Disable()
// {
//IAP_CONTR=0;
// IAP_CMD=0;
// IAP_TRIG=0;
// IAP_ADDRH=0;
//IAP_ADDRL=0;
// }
void Sector_Erase(unsigned int addr)
{
//addr=(addr&0xfe00); //地址小于0xfe00?
ISP_ADDRH = (addr>>8);
ISP_ADDRL = (addr&0x00ff);
ISP_CONTR = ISP_IAP_ENABLE; //0x81
ISP_CMD = ISP_IAP_SECTOR_ERASE; //3
ISP_TRIG = 0x46;
ISP_TRIG = 0xb9;
_nop_();
_nop_();
_nop_();
ISP_CONTR = 0x00;
ISP_CMD = 0x00;
ISP_TRIG = 0x00;
}
void delay(uchar ms)
{
uchar m;
while (ms--)
{
for (m=0;m<250;m++)
{;}
}
}
这个程序省略了纬纱信号采样及数字滤波,熟悉剑杆机的朋友可以自己补充。
河北 庞青