⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 play.#2

📁 该程序是基于c8051f的红外线发射率的测量程序
💻 #2
📖 第 1 页 / 共 5 页
字号:
//*********************************************************************
#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 + -