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

📄 fsdfs.txt

📁 针对被控对象存在的大惯性、纯滞后的特点,采用了模糊控制方式的控制策略,设计了一种高精度温度控制算法
💻 TXT
字号:
/***************************************************************************************************************
												水箱温度模糊控制系统设计

调试现象:
			1 LED显示有问题
				原因:温度转换时间过长(超过1S)
				解决办法:去除1S延时
				结果:LED正常显示,但是亮度不够  
LED:	采取中断显示 ,中断时间50ms  ,使用定时器1  
																				致用楼311实验室 
****************************************************************************************************************/

#include <at89x52.h>
#include <absacc.h>

#define led_data XBYTE[0xe000]    /*显示数据端口*/
#define led_sel XBYTE[0xc000]     /*显示器选择端口*/
#define key XBYTE[0xa000]     /*键盘端口*/
#define uchar unsigned char
#define uint unsigned int 

sbit ddata=P1^0;		//输入温度数据端 
sbit outPCM=P1^7;		//控制输出端
sbit LED1=P1^1;			//上限温度报警指示灯 
sbit LED2=P1^2;			//下限温度报警指示灯 
sbit LED3=P1^3;			//通电期间指示灯 

sbit LED4=P1^4;			//开启温度控制模式
sbit LED5=P1^5;			//修改参数模式 
sbit LED6=P1^6;			//随机显示温度模式 

uchar code table[10]={ 0x3F,0x06,0x5B,0x4F,0x66,
                         0x6D,0x7D,0x07,0x7F,0x6F,0x39};			/*LED显示变换*/
uchar code ttable[16]={0x0,0x01,0x01,0x02,0x03,0x03,
						 0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
uchar code Ucontrol[7][7]={{6,6,6,6,5,4,3},
							{6,6,5,5,4,3,3},
							{6,5,5,4,3,3,2},
							{5,4,4,3,2,2,1},
							{4,3,3,2,1,1,0},
							{5,3,2,1,1,0,0},
							{3,2,1,0,0,0,0}}; //输出控制规则表 
uchar code period[2]={6,12};
uchar code TT[5]={2,4,6,8,10};
uchar code Kec[2]={1,2};
uchar code Ku[2]={1,2};

uchar Temp[6]={0,0,0,10,0,0};
uchar para[6]={0,6,8,1,50,1);	//参数选择    1 Ts 采样周期
											//2 TT 温度常数 ,改变论域 T0 
											//3 Ku  通电时间常数 Ton
											//4 TR 给定温度
											//5 Kec 温度变化常数 K 
uchar count[2];		//中断次数
					//count[0]输出控制时间的中断次数 count;
					 //count[1]采样中断次数 count_T;
uchar read_flag;	//采样标志 
uchar outTime;		//输出控制时间 
/*--------------------------------------------------------------------------------------------------------------
												延时子程序

--------------------------------------------------------------------------------------------------------------*/
void delay(uint t)
{
	uint i;
	while(t--)
	     {
		 	for(i=0;i<125;i++)
			   {
			   }
		  }
}

/*--------------------------------------------------------------------------------------------------------------
												初始化DS18B20子
产生复位脉冲
--------------------------------------------------------------------------------------------------------------*/
 void TxReset(void)
 {
 	uint i;
	ddata=0;

	i=100;							  //拉低约900us
	while(i>0)
	     {
		 	i--;
		  }

	ddata=1;
	i=4;
	while(i>0)
	     {
		 	i--;
		  }
}

/*--------------------------------------------------------------------------------------------------------------
												  等待子程序
等待应答脉冲
--------------------------------------------------------------------------------------------------------------*/
void RxWait(void)
{
	uint i;
	while(ddata);
	while(~ddata);
	i=4;
	while(i>0)
		{
			i--;
		}
}
/*--------------------------------------------------------------------------------------------------------------
												读取一位数据子程序

--------------------------------------------------------------------------------------------------------------*/
bit RdBit(void)
{
	uint i;
	bit b;
	ddata =0;
	i++;
	ddata=1;
	i++;
	i++;

	b=ddata;
	i=8;
	while(i>0)
		{
			i--;
		}
	return(b);
}
/*--------------------------------------------------------------------------------------------------------------
												读取一个字节

--------------------------------------------------------------------------------------------------------------*/
uchar RdByte(void)
{
	uchar i,j,b;
	b=0;
	for(i=1;i<=8;i++)
		{
			j=RdBit();
			b=(j<<7)|(b>>1);
		}
	return(b);
}
/*--------------------------------------------------------------------------------------------------------------
											写数据的一个字节

--------------------------------------------------------------------------------------------------------------*/
void WrByte(uchar b)
{
	uint i;
	uchar j;
	bit btmp;
	for(j=1;j<=8;j++)
		{
			btmp=b&0x01;
			b=b>>1;
			if(btmp)
				{
					ddata=0;
					i++;
					i++;
					ddata=1;
					i=8;
					while(i>0)
						{
							i--;
						}
					}
			   else
			   	{
					ddata=0;
					i=8;
					while(i>0)
						{
							i--;
						}
					ddata=1;
					i++;
					i++;
				}
			}
}
/*--------------------------------------------------------------------------------------------------------------
												启动温度转换

--------------------------------------------------------------------------------------------------------------*/
void convert(void)
{
	TxReset();
	RxWait();
	delay(1);
	WrByte(0xcc);
	WrByte(0x44);
}
/*--------------------------------------------------------------------------------------------------------------
												读取温度
读取温度数据 
--------------------------------------------------------------------------------------------------------------*/
void RdTemp(void)
{
	uchar tlsb,thsb;//存储温度数据,tlsb存低位,thsb存高位  

	TxReset();
	RxWait();
	delay(1);
	WrByte(0xcc);
	WrByte(0xbe);
	tlsb=RdByte();
	thsb=RdByte();

	temp_dec=ttable[(tlsb&0x0f)];			   //得到二进制小数位,在查表得到要显示的小数(保留小数点后一位)

	temp_int=((tlsb&0x0f0)>>4)|((thsb&0x0f)<<4);   //得到整数位  	
}		

/*-----------------------------------------------------------------------------------------------------------------
															查表求行向量 Ec  
说明:每个采样周期 查 一次表   返回 行值   
-----------------------------------------------------------------------------------------------------------------*/
uchar table_Ec(uchar Tempr1,uchar Tempr2)
{
	uchar row;
	
	uchar Ec;
	uchar Ec1;
	uchar Ec2;
	uchar Ec3;

	bit flag;

	Ec1=Kec;
	Ec2=2*Kec;
	Ec3=3*Kec;

	if(Tempr2>=Tempr1)
		{
			flag=0;
			Ec=Tempr2-Tempr1;
		}
	else
		{
			flag=1;
			Ec=Tempr1-Tempr2;
		}
	if(Ec>=Ec3)
		{
			if(flag)
				row=0;
			else
				row=6;
		}
	else if(Ec>=Ec2&&Ec<=Ec3)
		{
			if(flag)
				row=1;
			else
				row=5;
		}
	else if(Ec>=Ec1&&Ec<=Ec2)
		{
			if(flag)
				row=2;
			else
				row=4;
		}
	else
		{
				row=3;
		}
return(row);
}
/*-----------------------------------------------------------------------------------------------------------------
															查表求列向量 E 
说明:每个采样周期 查 一次表   返回  列  值  
-----------------------------------------------------------------------------------------------------------------*/
uchar table_E(void)
{
	uchar column;
	
	uchar E1;
	uchar E2;
	uchar E3;
	uchar E;
	
//	uchar Tempr;	//存储温度数据 

	uchar flag;

	E1=TT/2;
	E2=TT+E1;
	E3=2*TT+E1;

	if(TR>=temp_int)
		{
			flag=1;
			E=TR-temp_int;
		}
	else
		{
			flag=0;
			E=temp_int-TR;
		}
	if(E>=E3)
		{
			if(flag)
				column=0;
			else
				column=6;
		}
	else if(E>=E2&&E<=E3)
		{
			if(flag)
				column=1;
			else
				column=5;
		}
	else if(E>=E1&&E<=E2)
		{
			if(flag)
				column=2;
			else
				column=4;
		}
	else
		{
				column=0;
		}
return(column);
}
/*--------------------------------------------------------------------------------------------------------------
												LED显示子程序 
功能:将转换后的数据通过LED显示出来
--------------------------------------------------------------------------------------------------------------*/
void show(void)
{
	uchar temp_int1;
	uchar temp_int2;
	uchar temp_int3;

	temp_int1=temp_int/100;						  	//取出百分位
	temp_int2=(temp_int%100)/10;					//取出十位
	temp_int3=temp_int%10;							 //取出个位

	led_sel=0xfe;
	led_data=table[temp_int1];
	delay(1);

	led_sel=0xfd;
	led_data=table[temp_int2];
	delay(1);

	led_sel=0xfb;
	led_data=table[temp_int3]+0x80;
	delay(1);

	led_sel=0x0f7;
	led_data=table[temp_dec];
	delay(1);

	led_sel=0x0ef;					//显示温度表号 C 
	led_data=0x39;
	delay(1);

	led_sel=0x0df;					//显示输出通电时间 
	led_data=table[outTime];
	delay(1);
}
/*-----------------------------------------------------------------------------------------------------------------
															初始化子程序
-----------------------------------------------------------------------------------------------------------------*/
void Initial(void)
{

	TR=30;//给定温度
	Ku=1;
	Ts=6;//采样周期 
	TT=8;//温度常数 ,改变论域 T0 
	Kec=1;//温度变化常数 K 

	outTime=0;//输出控制时间 

	TMOD=0x01;
	TL0=0x3c;//初始化定时器0,定时50ms  
	TH0=0xb0; 	

	count_T=Ts*20;
}
/*-----------------------------------------------------------------------------------------------------------------
															键盘扫描子程序
-----------------------------------------------------------------------------------------------------------------*/
uchar keyscan(void)                        /*键盘扫描子程序*/
{   
    uint i;
	uchar button;
   	key=0xff;                        /*为输入键盘信息作准备*/
    led_sel=0xfe;
    led_data=0;

      if(key==0xfe) 
	   {
           for (i=0; i<500; i++);
		   button=1;  
  		   while(key==0xfe);
	   }

	   if(key==0xfd) 
	   {  
           for (i=0; i<500; i++);
           button=2;  
           while(key==0xfd);
	   }

	   if(key==0xfb) 
	   {  
           for (i=0; i<500; i++);
           button=3; 
           while(key==0xfb);
	   }
	   if(key==0xf7) 
	   {  
           for (i=0; i<500; i++);
           button=4; 
           while(key==0xf7);
	   }
return(button);	   	   
}
/*-----------------------------------------------------------------------------------------------------------------
															50ms定时子程序
说明:输出控制时间 
-----------------------------------------------------------------------------------------------------------------*/
void time0_50ms(void) interrupt 1
{
	uchar i=0;
	TL0=0x3c;
	TH0=0xb0;

	i++;
	if(i==count[0])
		outPCM=1;		//停电
	if(i==count_T)		//采样周期到 
		{
			i=0;	
			read_flag=1;
		}
}

/*-----------------------------------------------------------------------------------------------------------------
															参数显示子程序 
-----------------------------------------------------------------------------------------------------------------*/
void para_LED(uchar para,uchar n)
{
	led_sel=0xfe;
	led_data=table[para/10];
	delay(1);

	led_sel=0xfd;
	led_data=table[para%10];
	delay(1);

	led_sel=0x0df;					//显示输出通电时间 
	led_data=table[n];
	delay(1);
}	
/*-----------------------------------------------------------------------------------------------------------------
															主程序
-----------------------------------------------------------------------------------------------------------------*/
void main(void)
{
	uchar column;
	uchar row;
	uchar button;//按键1,2,3,4 分别表示K1 ,K2,K3,K4  
	uchar flag=2;//模式选择  2随机模式 1修改模式 4测控模式  
	uchar Tempr1;	//存储温度数据 
	uchar Tempr2;
	uchar para_count=0;	//参数选择 1 Ts 2 TT 3 Ku(通电时间常数)4 TR 5 Kec  (k)  
	uchar para;
	uchar read_flag1=1;

	Initial();
	para=Ts;
	
	do
		{
			button=keyscan();

			while(flag==2)				//随机模式 ,即随机显示温度  
				{
					//TR0=0;
					LED4=1;
					LED5=1;
					LED6=0;
					outTime=0;
					
					delay(1);
					convert();
					RdTemp();	//读取温度
					Tempr1=temp_int;
					show();		//显示温度 

					button=keyscan();
					if(button==1)				//进入修改模式
						{
							flag=1;
							read_flag1=1;
							TR0=0;
							break;
						}
					if(button==4)				//进入测控模式 
						{
							flag=4;
							read_flag1=1;
							break;
						}
					
				}

			while(flag==1)				//修改模式 
				{				
					LED4=1;
					LED5=0;
					LED6=1;

					button=keyscan();
					switch(button)
						{
							case 1:
								{
									para_count++;
									if(para_count>5)
										para_count=1;	
								 }break;
							case 2:
								{
									if(para_count==1)
										Ts++;
									else if(para_count==2)
										TT++;
									else if(para_count==3)
										Ku++;
									else if(para_count==4)
										TR++;
									else 
										Kec++;
								 }break;
							case 3:
								{
									if(para_count==1)
										Ts=Ts-1;
									else if(para_count==2)
										TT=TT-1;
									else if(para_count==3)
										Ku=Ku-1;
									else if(para_count==4)
										TR=TR-1;
									else 
										Kec=Kec-1;
								  }break;	
							case 4:
									flag=2;	break;
							}
					
							if(para_count==1)				
										para=Ts;
									else if(para_count==2)
										para=TT;
									else if(para_count==3)	
										para=Ku;
									else if(para_count==4)
										para=TR;
									else 	
										para=Kec;
						para_LED(para,para_count);
						if(flag==2)				//进入随机模式 
							{
								TR0=0;
								break;
							}
					}
	
			while(flag==4)			//测控模式 
				{
					LED4=0;				
					LED5=1;
					LED6=1;
					
					if(read_flag||read_flag1)				//采样
						{
							Tempr2=temp_int;		//纪录当前采样值 
						
							column=table_E();
							row=table_Ec(Tempr1,Tempr2);
							outTime=Ucontrol[column][row];//查控制规则表 
							count=outTime*20;
							TR0=1;
							
							if(outTime>0)
								outPCM=0;				//通电
							else
								outPCM=1;

							Tempr1=Tempr2;			//纪录上次采样值 
							read_flag1=0;
							read_flag=0;
						}
					
					convert();
					RdTemp();	//读取温度		
					show();	
					
					button=keyscan();
					if(button==1)			//退出测控模式 ,进入 修改 模式  
						{
							flag=1;
							TR0=0;
							break;
						}
					else if(button==2)			//推出测控模式,进入随机模式  
						{
							flag=2;
							TR0=0;
							break;
						}
					else
						flag=4;
					
					}
					
		 }
	while(1);
		
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -