您尚未登录。

楼主 #1 2018-05-08 21:16:54

演技担当黄晓明
会员
注册时间: 2017-10-17
已发帖子: 184
积分: 122.5

仿人控制 300-1000全范围控温精度+-1度,丢入冷物料3分钟快速升温最高超调2度

硬件:
1。用可控硅控制4.5KW电炉 用K型热电偶采集温度,采用cs1242做温度转换,可以到正负一度的精度


实验目标:
在300度到1000度内可对任意设定的温度恒温,精度先做到+/-1度吧

基本的控制实现方法:
因为是对加热的炉子温度进行控制,属于滞后效应系统,所以采样周期先定为2秒(这里指的是PID计算的周期,注意我的温度采样是实时的),所以CPU外部中断次数为15次/S,对应的功率计算结果输出为0~255,就是说把这2秒钟划分为255等份,根据计算的结果来决定在这2秒钟内应该加热多少等份


下面是控制曲线输出的表格 0.1度为单位
升温曲线



源码下载:  https://whycan.cn/files/members/338/fuzzy.rar

最近编辑记录 演技担当黄晓明 (2018-05-08 21:18:42)

离线

楼主 #2 2018-05-08 21:19:36

演技担当黄晓明
会员
注册时间: 2017-10-17
已发帖子: 184
积分: 122.5

Re: 仿人控制 300-1000全范围控温精度+-1度,丢入冷物料3分钟快速升温最高超调2度

/******************************************************************************
	FILE:       FUZZY.C
	POPURSE:     
	WRITER:     Xukaiming 
	DATE:       2007.03.08
******************************************************************************/
#include "main.h"
#include "task.h"
#include "fuzzy.h"
#include "ied_ctrl.h"
#include "math.h"     
#include "x5043.h" 
#include "manctrl.h"


#define ERRORCNT  9			//误差记录
#define DERRORCNT 10		//误差变化率记录
//#define DOOROPENSPEED  -15L	//开门时的升温速度,如果低于此温度,认为电阻丝的热量完全散发出来或者开门升温
xdata long DOOROPENSPEED = -15L;
#define MAXNEGINTERG   (-200L*KI/Ki) 
extern code unsigned int K_Temp_Tab[];
typedef struct AI_CONTROL
{
	long gDest;  			//目标温度的AD值
	long CTEMP;				//开始控制温度

	long Error[ERRORCNT];			//偏差
	long dErr[DERRORCNT] ;			//偏差变化率	   
	long ECSUM;				//10S内的偏差变化率之和		    
	long SumErrLimit 	; 	//加热初值			 
	
	long PreviewOut;
	long HFDownTemp ;
	long du;
	long DoorOpenValue;	//保存炉子门状态  	 
	char LowSpeedCnt;
	unsigned int  iDestTemp;	//目标温度值
	unsigned int  iStableCnt;	//输出稳定次数
	unsigned int  iPreStabCnt;	//保存的稳定次数
};

#define  Kp		15           		//输出变量u比例因子
#define  Ki		1/10 				//衰减系数;		    
#define  KI		15

//Kp 变小的时候 ki要变大	  
xdata   struct AI_CONTROL Ai_CTRL;						  
void TaskFuzzy(void)
{
	char cnt;
	_nop_();
 	 
	if(IED.lADTemp>MAX_TEMP)        			 //超温保护
	{
		SetPWM(PWM_PITCED);	  
		return ;  
	}  
	//求偏差
	for(cnt=ERRORCNT-1;cnt>0;cnt--)
	{
		Ai_CTRL.Error[cnt]	= Ai_CTRL.Error[cnt-1];	
	}                    //保存上次偏差值  
	Ai_CTRL.Error[0]	= (long)(((Ai_CTRL.gDest-IED.lADTemp)/KC));	
	for(cnt=DERRORCNT-1;cnt>0;cnt--)
	{
		Ai_CTRL.dErr[cnt]	= Ai_CTRL.dErr[cnt-1];	
	}                  	//保存上次偏差率值
	Ai_CTRL.dErr[0] 	= Ai_CTRL.Error[0]-Ai_CTRL.Error[1];														//计算偏差变化率    
	Ai_CTRL.ECSUM  		= Ai_CTRL.dErr[0] + Ai_CTRL.dErr[1] + Ai_CTRL.dErr[2] + Ai_CTRL.dErr[3] + Ai_CTRL.dErr[4];	//10s的温升速率	  =iol		 
	if(Ai_CTRL.Error[0]<Ai_CTRL.CTEMP)      
	{  
		
		if(((Ai_CTRL.Error[0]*Ai_CTRL.dErr[0])>0) || ((Ai_CTRL.Error[0]==0) &&( Ai_CTRL.dErr[0]!=0)))   //误差变大的情况
		{ 
			Ai_CTRL.SumErrLimit +=Ai_CTRL.Error[0]; 					//误差变大的时候,求积分			
			if(Ai_CTRL.SumErrLimit<MAXNEGINTERG)						//限幅,如果超过负的最大值, 保持为负的最大值
				Ai_CTRL.SumErrLimit=MAXNEGINTERG;
			//////////////////////////////////////////////////////////// 
			Ai_CTRL.du = Ai_CTRL.Error[0]*Kp+Ai_CTRL.SumErrLimit*Ki/KI*Kp;	  	//增益抑制模式	                         //				
		}
		else              								//开环保持模式
		{
			if(((Ai_CTRL.Error[0]*Ai_CTRL.dErr[0])<0)||(Ai_CTRL.dErr[0]==0))				  	//误差变小的情况
			{		   
				Ai_CTRL.du =  Ai_CTRL.SumErrLimit*Ki/KI*Kp;                  
			}
			else
			{
				Ai_CTRL.du = Ai_CTRL.PreviewOut;	
			}
		}  							 
	}
	else	
		Ai_CTRL.du=PWM_PERIOD;      //升温

  
	if(Ai_CTRL.du<0) Ai_CTRL.du=0; 
	if(Ai_CTRL.du>PWM_PERIOD) Ai_CTRL.du=PWM_PERIOD;  
																	    
#ifdef _DEBUG   
	printf("%ld,",Ai_CTRL.CTEMP);
	printf("%ld,%ld,",Ai_CTRL.Error[0],Ai_CTRL.dErr[0] );
	printf("%ld,%ld,%d\n",Ai_CTRL.ECSUM,Ai_CTRL.SumErrLimit,(int)Ai_CTRL.du);
#endif
	SetPWM((unsigned char)Ai_CTRL.du); 
	//保存上次输出
	Ai_CTRL.PreviewOut=Ai_CTRL.du;	   

}	 
  
//functions prototype
/************************************************************************
仿人智能控制器//Humanoid Intelligent Controller
************************************************************************/

/*******************************************************************
    模糊控制数据变量
********************************************************************/
void InitFuzzy(void)
{								   
	Ai_CTRL.DoorOpenValue = 0 ;//  重新统计升温速度	 
	Ai_CTRL.LowSpeedCnt=0;
	SetPWM(PWM_PITCED);
}

/*********************************************************************
    启动高温炉
**********************************************************************/
void CtrlStove(UCHAR cOpen, long lDefTemp, UCHAR cRate)
{
	xdata  StableTempTab  psTmpTab;
    //停止				  
    SuspendTask(TASK_FUZZY);
	InitFuzzy(); 
    if(cOpen)       //启动
    {								  
	    Ai_CTRL.gDest = (((double)(0xFFFFFFUL<<2))/5000000UL)*K_Temp_Tab[lDefTemp]+20;    //将 目标 温度值 转换 为 AD值   
		Ai_CTRL.CTEMP = (1010L-lDefTemp) ; 				 							//控温范围 
        ActiveTask(TASK_FUZZY, PWM_SCAN);	
	 }										
}
/**********************************************************************
    设置PWM,PWM0控制高温炉
    16MHz时,T=2*512/16=64uS,F=42.666KHz,计数周期=256,占空比=0%--99.61%
***********************************************************************/
sbit POUT = P1^3;
char gcPoutTimer  = -1;

void StopPOut()
{
	POUT = 1;
}

 

void SetPWM(UCHAR cPeriod)
{   
	/*  
	CMOD  = 0x00; 					// Setup PCA timer
									// Configure PCA0 Counter operating mode
	CCAP0L=CCAP0H=cPeriod;			// Set duty for TCM0
	CCON  =0x40;			
	CCAPM0=0x42;					// Set TCM0 operationg mode	 		
	*/
	long period;
	StopTimer(&gcPoutTimer); 
	POUT = 1;
	period = PWM_SCAN*cPeriod/255/10;
	if(period>0)
	{
		POUT = 0; 
		gcPoutTimer = StartTimer(TIMER_MODE_ONCEROUTINE,period,StopPOut,0);
	}
	 
}
 

离线

#3 2018-05-09 06:09:38

bunny
会员
注册时间: 2020-05-23
已发帖子: 154
积分: 154

Re: 仿人控制 300-1000全范围控温精度+-1度,丢入冷物料3分钟快速升温最高超调2度

赞!!!!!!!

离线

#4 2020-07-23 13:57:35

wenhuaxiao
会员
注册时间: 2020-07-23
已发帖子: 2
积分: 2

Re: 仿人控制 300-1000全范围控温精度+-1度,丢入冷物料3分钟快速升温最高超调2度

在300度到1000度内可对任意设定的温度恒温,精度先做到+/-1度,这个要学学

离线

#5 2020-10-11 14:59:05

lcfmax
会员
注册时间: 2018-04-13
已发帖子: 325
积分: 268.5

Re: 仿人控制 300-1000全范围控温精度+-1度,丢入冷物料3分钟快速升温最高超调2度

厉害,这个要学习

离线

#6 2020-10-12 09:09:38

wm20031015
会员
注册时间: 2017-10-18
已发帖子: 66
积分: 170

Re: 仿人控制 300-1000全范围控温精度+-1度,丢入冷物料3分钟快速升温最高超调2度

小明好牛B

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn