/***参数设置,开模数计数,秒脉冲计时***************/
/***实现功能:检测报警信号,脱模剂开模数计数信号***/
/***参数:1:脱模剂开模数 2:喷雾时间 3:延时时间 ***/
/***串口接收触摸屏参数设置字符串,接收并保存******/
/***端子输入口读开模数,比较设定值后输出到电磁阀**/
/***端子输入口读报警信号,到设定值关闭电机及加热**/
#include <REG52.H> //2023 2 28 L422 CODE2785
#include <intrins.H>
#include "stdio.h"
#define uint unsigned int
#define uchar unsigned char
#define WT_12M 0x83 //IAP_CONTR
//#define WT_30M 0x80 频率30M
//#define WT_24M 0x81 频率24M
//#define WT_20M 0x82 频率20M
//#define WT_12M 0x83 频率12M
//#define WT_6M 0x84 频率6M
//#define WT_3M 0x85 频率3M
//#define WT_2M 0x86 频率2M
//#define WT_1M 0x87 频率1M
#define IAP_ADDRESS 0x0400 //EEPROM首地址
typedef unsigned char BYTE;
typedef unsigned int WORD;
uchar s;
sbit AUX=P3^2; /****RoLa***/
sbit MD0MD1=P1^7; /****RoLa***/
sbit OUT1=P3^4; /****输出***/
sbit OUT2=P3^5; /****输出***/
sbit WARNING=P5^5; /****输入***/
sbit INTPUT1=P5^4; /****输入***/
sbit BP=P1^0; /***输出LED指示***/
uchar v; /*从机号*/
uchar Modulus; //开模数
uchar Spray_Time; //喷雾时间
uchar Delay_Time; //延时时间
uchar kcounter,kstatus; //按键计数标志 按键状态标志
bit Receive_Flag; //串口数据缓冲接收标志
bit WARNING_Flag; //低电平报警标志
bit S_Flag; //秒计时标志
uint WARNING_Time; //报警计时计数器
uchar DAT2=0;
static uint val1,val2,val3,val4;
uint val5; //机器编号
uint SS=0;
uint TIME=0; //实际开模数
uint a[10]; //定义数组a 存储串口数据串
/*---------------延时子程序----------------*/
void delay1 (uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<200;j++)
;
}
/*------------------延时子程序------------------------*/
void delay10ms(uint x)
{
uint i, j;
for (i=0;i<x;i++)
for (j=0;j<500;j++);
}
/*-----------延时100ms子程序12MHz --------*/
void Delay_100ms(uint x) //
{
uint i,j;
for(i=0;i<x;i++)
{
for(j=0;j<18000;j++);
}
}
/****************按键计数器状态寄存器归零*************/
void RstKey()
{
kcounter=0; //按键计数器归零
kstatus=0; //状态寄存器归零
}
/*****************按键低电平检测函数*****************/
void LowVoltKey(void) //按键计数器状态标志加一
{
kcounter++;
kstatus++;
_nop_(); //延时
}
/*****************按键高电平检测函数*****************/
void HighVoltKey(void) //按键计数器加一 状态标志归零
{
kcounter++; //按键计数器加一
kstatus=0; //按键状态标志归零
_nop_(); //延时
}
/*----关闭IAP----------------------------*/
void IapIdle()
{
IAP_CONTR=0; //关闭IAP功能 ISP/IAP 控制寄存器
IAP_CMD=0; //清除命令寄存器
IAP_TRIG=0; //清除触发寄存器
IAP_ADDRH=0X80; //将地址设置到非IAP区域
IAP_ADDRL=0;
}
/*-从ISP/IAP/EEPROM区域读取一字节-*/
char IapRead(int addr)
{
char dat;
IAP_CONTR = WT_12M; //使能IAP ISP/IAP 控制寄存器
IAP_CMD = 1; //设置IAP读命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
dat = IAP_DATA; //读IAP数据
IapIdle(); //关闭IAP功?
return dat;
}
/*********字节写*********************/
void IapProgram(int addr, char dat)
{
IAP_CONTR = WT_12M; //使能IAP
IAP_CMD = 2; //设置IAP写命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写IAP数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
IapIdle(); //关闭IAP功能
}
/*---扇区擦除---------------*/
void IapErase(int addr)
{
IAP_CONTR = WT_12M; //使能IAP
IAP_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IapIdle(); //关闭IAP功能
}
/*************写参数到EEPROM*******************************/
void Write_EepromTime()
{
IapErase(IAP_ADDRESS); //扇区擦除
IapProgram(IAP_ADDRESS+0,val1/256); /*开模数高八位*/
IapProgram(IAP_ADDRESS+1,val1%256); /*开模数低八位*/
IapProgram(IAP_ADDRESS+2,val2/256); /*喷雾时间高八位*/
IapProgram(IAP_ADDRESS+3,val2%256); /*喷雾时间低八位*/
IapProgram(IAP_ADDRESS+4,val3/256); /*喷雾延时高八位*/
IapProgram(IAP_ADDRESS+5,val3%256); /*喷雾延时低八位*/
IapProgram(IAP_ADDRESS+6,val4/256); /*报警延时关高八位*/
IapProgram(IAP_ADDRESS+7,val4%256); /*报警延时关低八位*/
IapProgram(IAP_ADDRESS+8,val5/256); /*系统高八位*/
IapProgram(IAP_ADDRESS+9,val5); /*系统低八位*/
}
/***********************************/
void red_eeprom(void)
{
uint m,n;
m=IapRead(IAP_ADDRESS+0); //开模数高八位
n=IapRead(IAP_ADDRESS+1); //开模数低八位
val1=m*256+n; //开模数
m=IapRead(IAP_ADDRESS+2); //喷雾时间高八位
n=IapRead(IAP_ADDRESS+3); //喷雾时间低八位
val2=m*256+n; //喷雾时间
m=IapRead(IAP_ADDRESS+4); //喷雾延时时间高八位
n=IapRead(IAP_ADDRESS+5); //喷雾延时时间低八位
val3=m*256+n; //喷雾延时时间
m=IapRead(IAP_ADDRESS+6); //报警延时关加热电机高八位
n=IapRead(IAP_ADDRESS+7); //报警延时关加热电机低八位
val4=m*256+n; //报警延时关加热电机时间
val5=IapRead(IAP_ADDRESS+8); //备用高八位
}
/*------------初始化串口---------------------*/
void InitUart()
{
SCON=0X50; //8位数据,可变波特率
AUXR|=0x01; //串口1选择定时器2为波特率发生器
AUXR|=0X04; //定时器2时钟为Fosc,即1T
T2L=0XE0; //设置定时器处置 110592》9600
T2H=0XFE; //设置定时器处置 110592》9600
AUXR|=0X10; //启动定时器2
TI=1;
ES=1; //
EA=1;
}
/**************串口发送*****************************/
void Send(uchar temp)
{
unsigned serial;
serial=temp;
SBUF=(uchar)temp;
while(TI!=1);
TI=0;
}
/*--------UART中断服务程序---串口4接收触摸屏数据---*/
void Uart() interrupt 4 using 1
{
uchar i;
if(RI)
{
if(SBUF==0XFA) //触摸屏结束码
{
Receive_Flag=1; //接收数据标志置一
RI=0; //
i=0; //数组计数器归零
}
else
{
a[i]=SBUF; //数组下标位置的数据等于SBUF
RI=0; //
i++;
}
}
}
/**************定时器0中断*********************/
void TM0_Isr() interrupt 1
{
SS++;
if(SS>=12000) //6000
{
SS=0;
S_Flag=1; //秒计时标志
}
}
/*------------------主循环程序----------------*/
void main( ) /*主程序开始*/
{ /**加一**/
AUXR=0X80; //STC系列的1T 设置
TL0=0x66; //65536-11.0592M/12/1000
TH0=0xfc;
ET0=1; //使能定时器中
TR0=1; //启动定时器
BP=1;
delay1(2000);
BP=0;
delay1(2000);
BP=1;
delay1(2000);
BP=0;
delay1(2000);
BP=1;
delay1(2000);
BP=0;
InitUart(); //初始化串口
MD0MD1=0; //
P_SW1=0x00; //RXD/P3.0, TXD/P3.1
delay10ms(200);
printf("0XFF,0XFF,0XFF");
delay10ms(200);
Send(0XBB);
delay10ms(200);
Send(0XBB);
delay10ms(200);
Send(0XBB);
red_eeprom();
P_SW1=0x40; //RXD_2/P3.6, TXD_2/P3.7
delay10ms(100);
printf("0XFF,0XFF,0XFF"); //向串口屏发启动信号
delay1(20);
printf("t0.txt=\"系统启动\"" ); //
printf("XFF,XFF,XFF"); //向串口屏发启动信号
printf("t0.txt=\"系统启动\"" ); //
printf("0XFF,0XFF,0XFF"); //向串口屏发启动信号
delay10ms(50);
printf("n0.val=%d\xff\xff\xff",val1);
printf("n0.val=%d\xff\xff\xff",val1); //开模计数
printf("n1.val=%d\xff\xff\xff",val2); //喷雾时间
printf("n2.val=%d\xff\xff\xff",val3); //喷雾延时
printf("n3.val=%d\xff\xff\xff",val4); //关机延时 开模次数
printf("n5.val=%d\xff\xff\xff",val5); //系统
delay1(20);
Receive_Flag=0; //接收数据标志置零
S_Flag=0; //秒计时标志
WARNING_Time=0; //报警计时计数器
WARNING_Flag=0; //低电平报警标志
while(1)
{
if(Receive_Flag==1) //接收标志为1
{
Receive_Flag=0; //接收标志归零 重新接收
if (a[0]==0XC0&&a[1]==0X00) //
{
val1=a[3]*256+a[2]; //开模数
printf("n4.val=%d\xff\xff\xff",val1); //返回数据核对
}
else if (a[0]==0XC0&&a[1]==0X01)
{
val2=a[3]*256+a[2]; //喷雾时间
printf("n4.val=%d\xff\xff\xff",val2); //返回数据核对
}
else if (a[0]==0XC0&&a[1]==0X02) //
{
val3=a[3]*256+a[2]; //喷雾延时
printf("n4.val=%d\xff\xff\xff",val3); //返回数据核对
}
else if (a[0]==0XC0&&a[1]==0X03)
{
val4=a[3]*256+a[2]; //报警延时关电机加热
printf("n4.val=%d\xff\xff\xff",val4); //返回数据核对
}
else if (a[0]==0XC0&&a[1]==0X04)
{
val5=a[2]; //备用参数
printf("n4.val=%d\xff\xff\xff",val5); //返回数据核对
}
Write_EepromTime();
delay10ms(500);
printf("n0.val=%d\xff\xff\xff",val1); //开模计数
printf("n1.val=%d\xff\xff\xff",val2); //喷雾时间
printf("n2.val=%d\xff\xff\xff",val3); //喷雾延时
printf("n3.val=%d\xff\xff\xff",val4); //关机延时
printf("n5.val=%d\xff\xff\xff",val5); //系统
}
//
RstKey(); //开模完低电平信号
for(;kcounter<5;) //按键循环5次
{
if(!INTPUT1) //按键低电平
{
LowVoltKey(); //按键低电平 计数器加一状态标志加一
}
else if(~!INTPUT1) //按键高电平
{
HighVoltKey(); //按键计数器加一 状态标志归零
}
}
if(kstatus>=3) /*按键状态标志大于等于3为有效值*/
{
P_SW1=0x40; //RXD_2/P3.6, TXD_2/P3.7触摸屏显示开模数
delay10ms(100);
TIME++;
printf("n4.val=%d\xff\xff\xff",TIME); //实际开模数
if(TIME>=val1)
{
OUT1=0; /****输出***/
Delay_100ms(val2);
OUT1=1; /****输出***/
TIME=0;
}
RstKey();
for(;kcounter<5;) //按键循环5次
{
if(~!INTPUT1) //按键高电平
{
kcounter++; //高电平加1
BP=0;
delay1(20); //高电平闪烁指示
BP=1;
delay1(20); //高电平闪烁指示
}
else if(!INTPUT1) //按键低电平
{
kcounter=0; //低电平开模完未复位,继续循环检测
}
}
}
/**********************************************/
RstKey(); //按键复位
WARNING_Time=0; //报警计时计数器秒计时标志赋初始化值
for(;kcounter<8;) //按键循环8次
{
if(!WARNING) //按键低电平
{
LowVoltKey(); //按键低电平 计数器加一状态标志加一
}
else if(~!WARNING) //按键高电平
{
HighVoltKey(); //按键计数器加一 状态标志归零
}
}
if(kstatus>=5) /*按键状态标志大于等于5为有效值*/
{
RstKey(); //按键复位
WARNING_Flag=1; //启动低电平报警标志 while(WARNING_Flag)
RstKey(); //按键自动
do
{
if(~!WARNING) //按键低电平
{
kcounter++; //高电平加1
}
else if(!WARNING) //按键高电平
{
kcounter=0; //低电平开模完警报复位,继续循环检测
if(S_Flag==1) //定时器计时标志置位等于1
{
WARNING_Time++;
S_Flag=0; //关闭秒计时标志,等待定时器下一秒计时赋值
BP=~BP; //测试端口
printf("n6.val=%d\xff\xff\xff",WARNING_Time); //
}
if(WARNING_Time>=val4*60)
{
P_SW1=0x00; //RXD/P3.0, TXD/P3.1
delay10ms(200);
Send(val5);
delay10ms(200);
Send(val5);
delay10ms(200);
Send(val5);
S_Flag=0; //秒计时标志赋初始化值
WARNING_Time=0; //报警计时计数器秒计时标志赋初始化值
WARNING_Flag=0; //低电平报警标志
OUT2=0; //
}
} //检测到十次高电平,报警解除
if(kcounter>=10) /*按键状态标志大于等于10为有效值*/
{ //连续检测到10次高电平,警报解除
S_Flag=0; //秒计时标志赋初始化值
WARNING_Time=0; //报警计时计数器秒计时标志赋初始化值
WARNING_Flag=0; //低电平报警标志
}
}
while(WARNING_Flag);
P_SW1=0x40; //RXD_2/P3.6, TXD_2/P3.7 P_SW1=0x40;
}
}
} //2023 2 28 L422 CODE2785