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

📄 fuzzy_pid.c

📁 针对被控对象存在的大惯性、纯滞后的特点,采用了模糊控制方式的控制策略,设计了一种高精度温度控制算法
💻 C
📖 第 1 页 / 共 2 页
字号:
	uchar row;
	
	uchar Ec;
	uchar Ec1;
	uchar Ec2;
	uchar Ec3;

	bit flag;

	Ec1=para[4];
	Ec2=2*para[4];
	Ec3=3*para[4];

	if(Temp[6]>=Temp[5])
		{
			flag=0;
			Ec=Temp[6]-Temp[5];
		}
	else
		{
			flag=1;
			Ec=Temp[5]-Temp[6];
		}
	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 flag;

	E1=para[1]/2;
	E2=para[1]+E1;
	E3=2*para[1]+E1;

	if(para[3]>=Temp[4])
		{
			flag=1;
			E=para[3]-Temp[4];
		}
	else
		{
			flag=0;
			E=Temp[4]-para[3];
		}
	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=3;
		}
return(column);
}
/***************************************************************************************************
										加子程序 
***************************************************************************************************/
void Add_para(void)
{
		para[parameter]++;		
}
/***************************************************************************************************
										  减子程序 
***************************************************************************************************/
void delect_para(void)
{
	para[parameter]--;
	if(para[parameter]<0)
		para[parameter]=0;
}
/***************************************************************************************************
											参数选择子程序 
***************************************************************************************************/
void select_para(void)
{
	parameter++;
	if(parameter>4)
		parameter=0;
}
 
/***************************************************************************************************
															50ms定时子程序
说明: 
***************************************************************************************************/
void time0_50ms(void) interrupt 1
{
	TL0=-50000%256;
	TH0=-50000/256;

	count[2]++;

	if(count[2]==count[0])
		{
			outPCM=1;				//停电
			LED3=1;					//通电指示灯灭 
		}
	if(count[2]==count[1])		//采样周期到 
		{
			count[2]=0;	
			read_flag=1;
			LED2=~LED2;	
			serial_flag=1;		//串口发送数据标志
		 }
	// serial_flag=1;		//串口发送数据标志
	 
//	if(serial_flag)
//		{
//			printf("%d",Temp[4]);
		//printf("*");
//		}
}
/***************************************************************************************************
														得到输出通电时间 
***************************************************************************************************/
void take_time(void)
{
	uchar column;
	uchar row;

	
	column=table_E();
	row=table_Ec();							//得到输出控制规则表的行列 
	outTime=para[2]*Ucontrol[column][row];	
	count[0]=outTime*20;		//计算通电时间所需的中断次数  
}
/***************************************************************************************************
															输出控制 
***************************************************************************************************/
void out_control(void)
{

	
	if(outTime==0)
		outPCM=1;
	else
		{
		outPCM=0;					//通电
		LED3=0;						//通电指示灯亮 
		}
	TR0=1;						//开启定时器 
}
/***************************************************************************************************
															随机模式
***************************************************************************************************/
void rand_model(void)	
{
	LED4=1;
	LED5=1;
	LED6=0;		  					//相应指示灯亮

//	outTime=0;
	
	show_LED[3]=11;
	show_LED[4]=10;
	show_LED[5]=12;	 				//设定显示值
	while(1)
	{
	
		RdTemp();					//读取温度
		show_LED[0]=Temp[0];
		show_LED[1]=Temp[1];
		show_LED[2]=Temp[2];

		delay(1);					//延时1ms 以便读取 正确的温度 ,延时不够便显示初始温度85    
		show();
		Temp[5]=Temp[4];		   //记录当前温度
		
		keyscan();
		if(button==4||button==1)	   //模式转换
			{
				TR0=0;
				break;
			}
	/*	if(button==4)				//进入测控模式
			break;
		if(button==1)				//进入修改模式
			{
				TR0=0;
				break;
			}*/	
	}
 }
/***************************************************************************************************
															修改模式
***************************************************************************************************/
void trange_model(void)
{
	LED4=1;
	LED5=0;
	LED6=1;	  									
	
	while(1)
	{
		keyscan();
		switch(button)
			{
				case 1:select_para();break;
				case 2:Add_para();break;
				case 3:delect_para();break;
			//	case 4:TR0=0;break;
				default:break;
			 }
		if(button==4)							//进入测控模式
			{
				TR0=0;
				break;
			}
		show_LED[0]=para[parameter]/10;
		show_LED[1]=para[parameter]%10;
		show_LED[2]=12;
		show_LED[3]=12;
		show_LED[4]=12;
		show_LED[5]=parameter+1;
		show();
	}
	count[1]=para[0]*20;						//采样次数 
}
/***************************************************************************************************
															测控模式
***************************************************************************************************/
void control_model(void)
{
	LED4=0;				
	LED5=1;
	LED6=1;

	LED3=1;
	read_flag=1;
	serial_flag=1;

	TR1=1;
	TI=1;
	while(1)
		{
			RdTemp();
		
			if(read_flag)
				{
					Temp[6]=Temp[4]	;							//得到即时温度 
					take_time();			//得到通电时间 
					out_control();			//输出控制 
					read_flag=0;
					Temp[5]=Temp[6];			//纪录上次温度 
				}

			show_LED[0]=Temp[0];
			show_LED[1]=Temp[1];
			show_LED[2]=Temp[2];
			show_LED[3]=12;
			show_LED[4]=outTime/10;
			show_LED[5]=outTime%10; 
			show();
			
			if(serial_flag)
				{
					printf("%d\n",(uint)Temp[4]);
					//printf("*");
					serial_flag=0;
				}

			keyscan();
			if(button==1||button==2)		  //模式转换
				{
					TR0=0;
					TR1=0;
					outPCM=1;
					break;
				}
				
		}  
}
/***************************************************************************************************
															初始化子程序
***************************************************************************************************/
void Initial(void)
{
	EA=1;								  //开启中断允许
	ET0=1;								  //允许定时器0中断
	TMOD=0x21;							 //设定定时器0,工作方式1
	TL0=-50000%256;						//初始化定时器0,定时50ms  
	TH0=-50000/256; 

	TL1=0XFD;							//设置波特率9600bps
	TH1=0XFD;	
	SCON=0X50;							//串口控制寄存器,工作方式1(8位异步接受/发送器)允许接收

	count[1]=para[0]*20;				//采样次数 	
}
/***************************************************************************************************
															主程序
***************************************************************************************************/
void main(void)
{
	Initial();				   									//初始化
	while(1)
		{
			show();												//开机显示200701
			keyscan();										 	//扫面键盘
			while(button)
				{
					switch(button)
						{
							case 1:trange_model();break;		//进入修改模式
							case 2:rand_model();break;			//进入随机模式
							case 4:control_model();break;		//进入测控模式
							default:button=0;					//进入开启状态
						  }
				  }
		}
		
}

⌨️ 快捷键说明

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