📄 play.#1
字号:
//*********************************************************************
#include<c8051F120.h>
//*********************************************************************
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//*********************************************************************
//*********************************************************************
//此处的变量均是在程序中将要修改的值。
#define MUL 0.0167548825//与油缸直径有关的比例系数,此值的修改要根据油缸的直径来计算
#define PY 805 //此值为偏移值,与MUL配合使用,确定输出压力与油缸直径的关系
#define BL 0.2 //此值为实时压力在显示压力中的权重值,这里取0.2,表示在显示压力时,真实值
//占0.2的权重,那么理论压力值的权重就为(1-0.2)=0.8,换句话说,只要
//设定了真实压力值的权重BL值,那么理论压力值的权重在程序中自动就会为:
//(1-BL)。
//基本上只要修改以上3个变量即可。
//*********************************************************************
//*********************************************************************
//在LCD Flash中的各种预置画面的调用参数设定
#define WELCOMESCR 0x00//欢迎界面
#define MENUSELECT 0x01//菜单选择画面
#define PIDPARASET 0x04//PID参数设定画面
#define CLOSSYSTEM 0x06//关机画面
#define PARAUPLOAD 0x07//工艺参数上载画面
#define SENPARASET 0x0A//传感器温度、压力设置画面
#define NOWATERALM 0x0C//断水警告画面
#define PROPARASET 0x0E//工艺参数设定画面
#define WORKSCREEN 0x14//工作画面
#define COMMUERROR 0x19//与808P表通信错误画面
#define PRONUMSELT 0x1B//工艺序号选择画面
#define POWERERROR 0x1D//压力传感器错误画面
#define LOADINPARA 0x1F//正在上载参数画面
//AI808P
#define AIADDR 1//808P地址定义
//温度、压力参数初始化
#define HITEMP 1200
#define LOTEMP 400
#define HIPOWER 255
#define LOPOWER 13
//*********************************************************************
//P0.0 is UART0 TX0,P0.1 is UART0 RX0;
//P0.2 is UART1 TX1,P0.3 is UART1 RX1;
//P0.4 is /INT0,P0.5 is /INT1
//P0.6 is IIC SCL, P0.7 is IIC SDA;
sbit LCDDTR=P0^3;//LCD DTR
sbit NOWATER=P0^4;//water is bad
sbit DISTANCE=P0^5;//行程开关
sbit SCL=P0^6;
sbit SDA=P0^7;
sbit KEYY0=P1^0;
sbit KEYY1=P1^1;
sbit KEYY2=P1^2;
sbit KEYY3=P1^3;
sbit KEYY4=P1^4;
sbit KEYY5=P1^5;
sbit BEEP=P1^7;//Beep pin
sbit WIND=P2^0;//风机
sbit OUT1=P2^2;
sbit OUT2=P2^3;
sbit TG=P2^4;
sbit KEYX0=P2^5;
sbit KEYX1=P2^6;
sbit KEYX2=P2^7;
sbit TR=P3^0;
sbit HDISTANCE=P3^1;//高位行程开关
sbit LDISTANCE=P3^3;//低位行程开关
sbit MOTOR=P3^5;//motor control
sbit TPFC=P3^6;//two phase four cut-through control
//
#define TPFCOFF TPFC=1
#define TPFCON TPFC=0
#define MOTORRUN MOTOR=0
#define MOTORSTOP MOTOR=1
//*********************************************************************
uchar xdata key_temp[3]={0x3F,0x3F,0x3F};//用来记录3排按键值的寄存器组
bit keyturn;//用来防止重复按键标志位
uchar xdata KEY=0xFF;//键值
//
uchar xdata AIBUF[10];//808P表的回送数据缓冲寄存器
uchar xdata AIDATNUM;//808P表接收数据计数器
bit AIOVERFLG;//808P转换完成标志
bit TIMEFLG;//时间超过标志
uchar xdata AITIME;//808P转换时间记录
uchar xdata ERRORNUM;//AI808P错误次数
//
uchar xdata GYNUM=1;//工艺号
//
uint xdata PID_P;//PID参数
uint xdata PID_I;
uint xdata PID_D;
float xdata PrevError=0,PrevDError=0,POWEROUT=0;//PID参数计算时用到的差值种类
//
uint xdata TEMPRATURE_hi=HITEMP;//传感器温度设定最大值
uint xdata TEMPRATURE_lo=LOTEMP;//传感器温度设定最小值
uchar xdata POWER_hi=HIPOWER;//压力传感器压力最高值
uchar xdata POWER_lo=LOPOWER;//压力传感器压力最小值
uchar xdata REALPOWER;//实时压力值无符号字节型
float xdata REALPOWERF;//实时压力值浮点型
//
bit AUTO_MAN;//手动、自动识别为,1表示自动,0表示手动
bit MANFLG=1;//手动按钮轮训识别位
//
uchar xdata T3TIME=0;//定时器3的记数器
bit SAMPLEN=0;//开始采样标志
uint xdata TEMPTIME;//每一段的运行时间
uchar xdata SEGMENT;//当前段号
bit PIDEN=0;//PID计算使能位
//*********************************************************************
struct Process
{
uchar power[20];
uint time[20],temperature[20];
};
struct Process xdata GY[61];//定义61个工艺,每个工艺20段时间、温度、压力
//*********************************************************************
void PID(float POWERSET)
{
float dderror,derror,error;
uint dacvalue;
error=POWERSET-REALPOWERF;
derror=error-PrevError;
dderror=derror-PrevDError;
POWEROUT+=(float)PID_P/1000.0*derror+(float)PID_I/1000.0*error+(float)PID_D/1000.0*dderror;
if(POWEROUT<0)
{
POWEROUT=0;
}
if(POWEROUT>196360.0)//196350
{
POWEROUT=196360.0;
}
dacvalue=(uint)(POWERSET*MUL+PY);//这里必须有一个dacvalue与POWEROUT的关系比例式
DAC0L=dacvalue%256;
DAC0H=dacvalue/256;
PrevError=error;
PrevDError=derror;
}
//*********************************************************************
//delay function
void delay1s()
{
uchar i,j,k;
for(i=0;i<214;i++)
for(j=0;j<255;j++)
for(k=0;k<125;k++)
{}
}
void delay100us()
{
uchar i,j,k;
for(i=0;i<200;i++)
for(j=0;j<1;j++)
for(k=0;k<1;k++)
{}
}
void delay200ms()
{
uchar i,j,k;
for(i=0;i<43;i++)
for(j=0;j<255;j++)
for(k=0;k<255;k++)
{}
}
void delay5ms()
{
uchar i,j,k;
for(i=0;i<1;i++)
for(j=0;j<200;j++)
for(k=0;k<100;k++)
{}
}
void delay4us()
{
uchar i,j,k;
for(i=0;i<2;i++)
for(j=0;j<1;j++)
for(k=0;k<1;k++)
{}
}
//*********************************************************************
//LCD operate
void LCDDAT(uchar dat)
{
SFRPAGE=UART1_PAGE;
while(LCDDTR){}
SBUF1=dat;
while(!TI1){}
TI1=0;
SFRPAGE=LEGACY_PAGE;
}
void LCDASIIC()//设置LCD为西文显示
{
LCDDAT(0x1B);
LCDDAT(0x24);
}
void LCDHANZ()//设置汉字
{
LCDDAT(0x1B);
LCDDAT(0x23);
}
void LCDGBCOLOR(uchar fc,bc)//设置光标的前景色和背景色
{
LCDDAT(0x1B);
LCDDAT(0x38);
LCDDAT(fc);//前景色
LCDDAT(bc);//背景色
}
void LCDXY(uchar x,y)//光标移动到x,y处
{
LCDDAT(0x1B);
LCDDAT(0x47);
LCDDAT(x);
LCDDAT(y);
}
void LCDFCOLOR(uchar color)//设置前景色
{
LCDDAT(0x1B);
LCDDAT(0x43);
LCDDAT(color);
}
void LCDGBOC(uchar ok)//光标显示与否
{
LCDDAT(0x1B);
LCDDAT(0x57);
LCDDAT(ok);//光标显示
}
void LCDRSFT(uchar n)//光标右移n个字符
{
LCDDAT(0x1B);
LCDDAT(0x52);
LCDDAT(n);
}
void LCDOVERLAP(uchar dat)//覆盖、重叠显示方式选择
{
LCDDAT(0x1B);
LCDDAT(0x58);
LCDDAT(dat);
}
void LCDLINE(uchar color,x1l,x1h,y1l,y1h,x2l,x2h,y2l,y2h)//绘制直线
{
LCDDAT(0x1B);
LCDDAT(0x46);
LCDDAT(color);
LCDDAT(x1l);
LCDDAT(x1h);
LCDDAT(y1l);
LCDDAT(y1h);
LCDDAT(x2l);
LCDDAT(x2h);
LCDDAT(y2l);
LCDDAT(y2h);
}
void LCDSHOW(uchar number)//调用预置画面
{
LCDGBOC(0);//关光标
LCDXY(0,0);//将光标置于(0,0)处
LCDOVERLAP(0);//采用重叠方式
LCDDAT(0x1B);
LCDDAT(0x50);
LCDDAT(number);//调用相关画面
}
//*********************************************************************
void ALARM(uchar alarm)//报警画面显示函数
{
MOTORSTOP;//关电机
DAC0CN=0x00;//将DAC0CN寄存器的最高位DAC0EN置0表示关DAC0
SFRPAGE=DAC1_PAGE;
DAC1CN=0x00;
SFRPAGE=LEGACY_PAGE;
BEEP=1;//蜂明器鸣叫
LCDSHOW(alarm);//显示错误画面
}
//*********************************************************************
void AIWR(uchar dat)//向串口0写数据函数
{
SBUF0=dat;
while(!TI0){}
TI0=0;
}
//
uint WRITEAI(uchar addr,uint dat)//AI8080P写数据函数
{
uint CRC;
ERRORNUM=0;
again:
CRC=AIADDR+0x43+addr*256+dat;
AIOVERFLG=0;
AITIME=0;
delay100us();
TR=1;
delay100us();
REN0=0;//暂时不能接收数据
RI0=0;
TI0=0;
ES0=0;
AIDATNUM=0;
TIMEFLG=0;
AIWR(AIADDR+0x80);
AIWR(AIADDR+0x80);//传2遍地址
AIWR(0x43);
AIWR(addr);
AIWR(dat%256);
AIWR(dat/256);//传数据
AIWR(CRC%256);
AIWR(CRC/256);//传CRC码
delay100us();
ES0=1;//开串口0的中断,准备接收数据
REN0=1;//允许接收数据
TR=0;
while(!AIOVERFLG){}
TR=1;
if(TIMEFLG)
{
ERRORNUM++;
if(ERRORNUM == 10)
{
ALARM(COMMUERROR);
while(1){}
}
goto again;
}
else
{
CRC=AIBUF[0]+AIBUF[1]*256+AIBUF[2]+AIBUF[3]*256+AIBUF[4]+AIBUF[5]*256+AIBUF[6]+AIBUF[7]*256+AIADDR;
if(CRC != (AIBUF[8]+AIBUF[9]*256))//如果校验错误则表有问题
{
ERRORNUM++;
if(ERRORNUM == 10)
{
ALARM(COMMUERROR);
while(1){}
}
goto again;
}
else
{
return(AIBUF[0]+AIBUF[1]*256);
}
}
}
//
uint READAI(uchar addr)//AI808P读数据函数
{
uint CRC;
ERRORNUM=0;
again:
CRC=AIADDR+0x52+addr*256;
AIOVERFLG=0;
AITIME=0;
delay100us();
TR=1;
delay100us();
REN0=0;//暂时不能接收数据
RI0=0;
TI0=0;
ES0=0;
AIDATNUM=0;
TIMEFLG=0;
AIWR(AIADDR+0x80);
AIWR(AIADDR+0x80);//传2遍地址
AIWR(0x52);
AIWR(addr);
AIWR(0);
AIWR(0);//传数据
AIWR(CRC%256);
AIWR(CRC/256);//传CRC码
delay100us();
ES0=1;//开串口0的中断,准备接收数据
REN0=1;//允许接收数据
TR=0;
while(!AIOVERFLG){}
TR=1;
if(TIMEFLG)
{
ERRORNUM++;
if(ERRORNUM == 10)
{
ALARM(COMMUERROR);
while(1){}
}
goto again;
}
else
{
CRC=AIBUF[0]+AIBUF[1]*256+AIBUF[2]+AIBUF[3]*256+AIBUF[4]+AIBUF[5]*256+AIBUF[6]+AIBUF[7]*256+AIADDR;
if(CRC != (AIBUF[8]+AIBUF[9]*256))//如果校验错误则表有问题
{
ERRORNUM++;
if(ERRORNUM == 10)
{
ALARM(COMMUERROR);
while(1){}
}
goto again;
}
else
{
return(AIBUF[6]+AIBUF[7]*256);
}
}
}
//
void AISAVE()//存储工艺参数到AI808P表
{
uchar i;
for(i=0;i<20;i++)
{
WRITEAI(0x1A+i*2,GY[GYNUM].temperature[i]);
if(GY[GYNUM].time[i+1]==0)
{
WRITEAI(0x1B+i*2,-121);
break;
}
else
{
WRITEAI(0x1B+i*2,GY[GYNUM].time[i+1]);
}
}
}
//*********************************************************************
//键盘函数
uchar keycode()//该函数是在有键按下时才进入的函数
{
if(((key_temp[0] != 0x3F) && (key_temp[1] != 0x3F))||
((key_temp[0] != 0x3F) && (key_temp[2] != 0x3F))||
((key_temp[1] != 0x3F) && (key_temp[2] != 0x3F)) )//如果出现有2个以上键同时按下的情况则返回0xFF作
{
return (0xFF);//所以返回0xFF
}
else//如果不是则进行下面
{
if(key_temp[2] == 0x3F)//如果2排没有键按下,那么只有可能是0排或者1排有键按下,因为同时按下已经在前面过滤了
{
if(key_temp[0] != 0x3F)//如果0排有键按下,那么返回按下的键值
{
switch(key_temp[0])
{
case 0x3E: {return ('S');break;}//返回 确定
case 0x3D: {return ('C');break;}//返回 取消
case 0x3B: {return ('M');break;}//返回 手动
case 0x37: {return ('U');break;}//返回 上
case 0x2F: {return ('R');break;}//返回 右
default: {return (0xFF);break;}//避免同一排有2个以上的键按下
}
}
else//如果0排没有键按下,那么只有可能是1排了
{
switch(key_temp[1])
{
case 0x3E: {return ('0');break;}//返回 0
case 0x3D: {return ('1');break;}//返回 1
case 0x3B: {return ('2');break;}//返回 2
case 0x37: {return ('3');break;}//返回 3
case 0x2F: {return ('4');break;}//返回 4
case 0x1F: {return ('L');break;}//返回 左
default: {return (0xFF);break;}//避免同一排有2个以上的键按下
}
}
}
else//如果2排有键按下,则进行下面
{
switch(key_temp[2])//返回2排的键值
{
case 0x3E: {return ('5');break;}//返回 5
case 0x3D: {return ('6');break;}//返回 6
case 0x3B: {return ('7');break;}//返回 7
case 0x37: {return ('8');break;}//返回 8
case 0x2F: {return ('9');break;}//返回 9
case 0x1F: {return ('D');break;}//返回 下
default: {return (0xFF);break;}//避免不规范的组合键
}
}
}
}
//
void kbscan (void)//键盘扫面函数
{
uchar record[3];
KEYX0=0;KEYX1=0;KEYX2=0;
//P1 |=0x3F;
if((P1 & 0x3F) != 0x3F)//有键按下才进入
{
KEYX0=0;KEYX1=1;KEYX2=1;
record[0]=P1 & 0x3F;
KEYX0=1;KEYX1=0;KEYX2=1;
record[1]=P1 & 0x3F;
KEYX0=1;KEYX1=1;KEYX2=0;
record[2]=P1 & 0x3F;
if((key_temp[0]==record[0]) && (key_temp[1]==record[1]) && (key_temp[2]==record[2]))
{//第一次按下一个键,那么该条件等式可定不成立
if(keyturn)
{
KEY=keycode();
keyturn=0;
}
}
else
{
key_temp[0]=record[0];
key_temp[1]=record[1];
key_temp[2]=record[2];
keyturn=1;
}
}
else//当没有键按下时,初始化键盘相关参数为无键按下状态的值
{
key_temp[0]=0x3F;
key_temp[1]=0x3F;
key_temp[2]=0x3F;
KEY=0xFF;
}
}
//*********************************************************************
//IIC
//I2C函数*******************************************
//START()
void start (void)
{
SCL=0;
delay4us();
SDA=1;
delay4us();
SCL=1;
delay4us();
SDA=0;
delay4us();
SCL=0;
delay4us();
SDA=1;
delay4us();
}
//STOP()
void stop (void)
{
SCL=0;
delay4us();
SDA=0;
delay4us();
SCL=1;
delay4us();
SDA=1;
delay4us();
SCL=0;
delay4us();
}
//**********************
//ACK()
void ack (void)
{
SCL=0;
delay4us();
SDA=0;
delay4us();
SCL=1;
delay4us();
SCL=0;
delay4us();
SDA=1;
delay4us();
}
//NACK()
void nack (void)
{
SCL=0;
delay4us();
SDA=1;
delay4us();
SCL=1;
delay4us();
SCL=0;
delay4us();
}
//CACK()
bit cack (void)
{
bit flag;
SCL=0;
delay4us();
SDA=1;
delay4us();
SCL=1;
delay4us();
flag=SDA;
delay4us();
SCL=0;
delay4us();
return (flag);
}
//transbyte
void transmitbyte (uchar txdata)
{
uchar i;
for(i=8;i>0;i--)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -