#include <reg52.h>
#include <intrins.h>
#include "head.h"
#include "74HC595.c"
#include "at25128_e2prom.c"
#include "ds1302.c"
#include "uart.c"
//定义引脚
sbit led1=P0^1; // 温度显示指示灯
sbit led2=P0^2; // 湿度显示指示灯
sbit led3=P0^3; // 故障指示灯
sbit c_ctrlm1=P0^6; //控制信号1
sbit c_ctrlm2=P0^7; //控制信号2
sbit test1=P2^6; //检测驱动输出端信号1
sbit test2=P2^7; //检测驱动输出端信号2
sbit control=P0^5; // 压缩机启动信号
sbit pressure=P3^2; //压力开关启动信号
void delayms(uchar ms) //延时子程序
{
uint i;
for(ms;ms>0;ms--)
for(i=114;i>0;i--);
}
void init_interrupt(void) //外中断0初始化
{
EA=1;
EX0=1;
IT0=1;
}
void display_init() //开机显示初始化
{
EA=0;
Write_HC595( num_num[0],adress[0]);
Write_HC595( num_num[0],adress[1]);
Write_HC595( num_num[0],adress[2]);
Write_HC595( num_num[0],adress[3]);
Write_HC595( num_num[13],adress[3]);
//display_delays=1;
EA=1;
}
void save_fault(void) //开机存贮信号,以此判断在程序执行过程中有无复位现象,是硬件复位还是软件复位。
{
uchar adress_h,adress_l;
adress_h=fault_adress/256;
adress_l=fault_adress%256;
SPI_WriteByte(adress_h,adress_l,hour_test());//存入时间
fault_adress++;
adress_h=fault_adress/256;
adress_l=fault_adress%256;
SPI_WriteByte(adress_h,adress_l,min_test());
fault_adress++;
adress_h=fault_adress/256;
adress_l=fault_adress%256;
SPI_WriteByte(adress_h,adress_l,min_test());
fault_adress++;
adress_h=fault_adress/256;
adress_l=fault_adress%256;
SPI_WriteByte(adress_h,adress_l,reset_num); //存入复位次数
fault_adress++;
adress_h=fault_adress/256;
adress_l=fault_adress%256;
if(F0)
SPI_WriteByte(adress_h,adress_l,1);//利用PSW^5的值判断是软件复位还是硬件复位,用户标志位
else
SPI_WriteByte(adress_h,adress_l,0);//利用PSW^5的值判断是软件复位还是硬件复位。
fault_adress++;
adress_h=fault_adress/256;
adress_l=fault_adress%256;
SPI_WriteByte(0x00,0x02,adress_h);
SPI_WriteByte(0x00,0x03,adress_l);
}
void savedata(void) //存储运行数据,出现异常现象时,存储 ,当控制信号不等于相应的检测信号时,或者,两个控制信号同时为0时,存入数据
{
uchar adress_h,adress_l; // 另外,正常运行时,每周期存入两次数据,存入的时间点为每次电磁阀切换时存入
adress_h=data_adress/256;
adress_l=data_adress%256;
SPI_WriteByte(adress_h,adress_l,hour_test()); //存储时间
data_adress++;
adress_h=data_adress/256;
adress_l=data_adress%256;
SPI_WriteByte(adress_h,adress_l,min_test()); //存储时间
data_adress++;
adress_h=data_adress/256;
adress_l=data_adress%256;
SPI_WriteByte(adress_h,adress_l,sec_test());
data_adress++;
adress_h=data_adress/256;
adress_l=data_adress%256;
SPI_WriteByte(adress_h,adress_l,c_ctrlm1); //存储控制信号1
data_adress++;
adress_h=data_adress/256;
adress_l=data_adress%256;
SPI_WriteByte(adress_h,adress_l,test1); //存储检测信号1
data_adress++;
adress_h=data_adress/256;
adress_l=data_adress%256;
SPI_WriteByte(adress_h,adress_l,c_ctrlm2); //存储控制信号2
data_adress++;
adress_h=data_adress/256;
adress_l=data_adress%256;
SPI_WriteByte(adress_h,adress_l,test2); //存储检测信号2
data_adress++;
adress_h=data_adress/256;
adress_l=data_adress%256;
SPI_WriteByte(0x00,0x00,adress_h);
SPI_WriteByte( 0x00,0x01,adress_l);
}
void Init_sys()
{
int i;
//单片机引脚初始化
led1=1;
led2=1;
c_ctrlm1=1;
c_ctrlm1=1;
test1=1;
test2=1;
pressure=1;
// dryer_delays=0;
//芯片初始化 ,外存及时钟芯片
//Init_SPI_E2prom();
//Init_DS();
//变量初始化
write_flag=0; //存入故障数据标志
write_time=0; //控制每周期存入故障数据的个数
WDT_flag=0; //清看门狗标志
flag_fault=0; //运行过程中发现同时得电后,此标志有效,并用其控制故障处理时间
num=0; //控制干燥器运行周期
init_interrupt();//外中断0初始化
i=20;
while(i) //开机显示”0000“
{
i--;
display_init();
delayms(10);
led3=0; //点亮led3
}
fault_adress=SPI_ReadByte(0x00,0x02)*256+SPI_ReadByte(0x00,0x03); //从存贮 复位信息数据的指针的地址中读取最后一次指针数值
data_adress=SPI_ReadByte(0x00,0x00)*256+SPI_ReadByte(0x00,0x01); //同上
reset_num=SPI_ReadByte(0x00,0x04);
reset_num++;
save_fault(); //记录单片机复位信息,帮助判断故障类型(对于正常上电复位及看门狗复位暂不作区分,先以记录时间来区分)
//WDTRST=0x01e; //启动89S52内部看门狗
// WDTRST=0x0e1;
led3=1; //熄灭led3
}
void main()
{
Init_sys();
F0=1;
while(1)
{
// WDTRST=0x01e; //喂狗指令
// WDTRST=0x0e1;
delayms(1);//将来由其他函数代替
if((c_ctrlm1!=test1)||(c_ctrlm2!=test2)||(test1==0&&test2==0))
{
savedata();
c_ctrlm1=1; //发现运行不正常,及时关闭两个电磁阀
c_ctrlm2=1;
}
if(! display_delays) //实时显示运行数据 ,操作人员可根据此信息判断控制器运行是否正常
{
EA=0;
Write_HC595( num_num[c_ctrlm1],adress[0]);
Write_HC595( num_num[test1],adress[1]);
Write_HC595( num_num[c_ctrlm2],adress[2]);
Write_HC595( num_num[test2],adress[3]);
Write_HC595( num_num[13],adress[3]);
display_delays=1;
EA=1;
}
WDT_flag=1;//程序正确执行的标志
}
}
void ex0_inter() interrupt 0 using 0
{
// uchar i;
// sensor_flag=1;//只启动一次
c_ctrlm1=0;
c_ctrlm2=1;
c_ctrl_m1=1;
c_ctrl_m2=0;
// sth1x_sensor0(); // do not call other function in a interruption
// display();
// alarm_tem(temp);
TMOD=0x11; //Timier0 16 bit mode 定时器1、0工作在方式1
TH0=0x4C; //(65536-50000)/256;
TL0=0x00; //(65536-50000)%256;
TH1=0xdc;// 延时10ms
TL1=0x00;//
EA=1; //globle interrupt
ET0=1; //Timer 0 interrupt 禁止定时器0
TR0=1; //Timer 0 beginning
ET1=1; //Timer 0 interrupt
TR1=1; //Timer 0 beginning
}
void t0_iner() interrupt 1 using 1 //先执行外中断 ,此时c_ctrl_m1,c_ctrl_m2不再同时为1了
{
TH0=0x4C;// 中断定时50ms
TL0=0x00;//
if(!test1&&!test2) //中断时间到,先检测是否有同时的得电的情况,顺序非常重要!
{
c_ctrlm1=1;
c_ctrlm2=1;
c_ctrl_m1=1;
c_ctrl_m2=1;
flag_fault=20;
num=0; //回归初始状态
}
if(flag_fault)//确保不会有误动作
{
flag_fault--;
num=0;
c_ctrlm1=1;
c_ctrlm2=1;
} //同时失电,等待故障处理结束
if(num==1100) //60s ,闭气时间到,两个同时失电
{
c_ctrlm1=1;
c_ctrlm2=1;
write_flag=0;
}
if(pressure) //压力开关无效,停止工作。
{
TR0=0;
ET0=0;
TR1=0;
ET1=0;
num=0; ////////////////////////////////////////
c_ctrlm1=1;
c_ctrlm2=1;
c_ctrl_m1=1;///////可以做数码管显示的检测标志位
c_ctrl_m2=1;
}
if(!flag_fault&&!pressure) //故障处理结束,压力开关有效
if(c_ctrl_m1&&c_ctrl_m2)//在压力开关有效的前提下,状态标志异常,并且故障标志到期,则恢复电磁阀交替上电状态
{
c_ctrlm1=0;
c_ctrlm2=1;
c_ctrl_m1=1;
c_ctrl_m2=0;
num=0; //故障处理后,启动正常 工作状态
}
if(num==1200) //
{
num=0;
c_ctrlm1=c_ctrl_m1;
c_ctrlm2=c_ctrl_m2;
c_ctrl_m1=c_ctrlm2;
c_ctrl_m2=c_ctrlm1;
write_flag=0;
}
num++;
}
void t1_iner() interrupt 3 using 2
{
TH1=0xdc;// 延时10ms
TL1=0x00;//
TR1=0;
ET1=0;
// if(WDT_flag==1)
// {
// WDTRST=0x01e;
// WDTRST=0x0e1;
//}
if( display_delays)
display_delays--;
TR1=1;
ET1=1;
} |