OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9221|回复: 6

PID和仿人控制,孰优孰劣?300-1000控温精度+-1度,最高超调2度

[复制链接]

4

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2011-10-12
在线时间
9 小时
发表于 2012-6-30 11:11:19 | 显示全部楼层 |阅读模式
 硬件:
1。用可控硅控制4.5KW电炉 用K型热电偶采集温度,采用cs1242做温度转换,可以到正负一度的精度


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

基本的控制实现方法:
因为是对加热的炉子温度进行控制,属于滞后效应系统,所以采样周期先定为2秒(这里指的是PID计算的周期,注意我的温度采样是实时的),所以CPU外部中断次数为15次/S,对应的功率计算结果输出为0~255,就是说把这2秒钟划分为255等份,根据计算的结果来决定在这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 du;
  
long DoorOpenValue; //保存炉子门状态         
  
char LowSpeedCnt;
  
unsigned int iDestTemp; //目标温度值
};

#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);
  }

}
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2196
金钱
2196
注册时间
2012-2-8
在线时间
35 小时
发表于 2012-6-30 12:04:42 | 显示全部楼层
没看懂楼主发这帖子想说什么
https://github.com/roxma
回复 支持 反对

使用道具 举报

28

主题

306

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
1320
金钱
1320
注册时间
2012-6-3
在线时间
353 小时
发表于 2012-6-30 12:25:32 | 显示全部楼层
回复【楼主位】xukaiming:
---------------------------------
PID算法也没说明白啊?!!!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-6-30 13:24:48 | 显示全部楼层
我也没看懂...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

51

主题

1455

帖子

3

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2612
金钱
2612
注册时间
2011-1-25
在线时间
176 小时
发表于 2013-10-15 15:24:39 | 显示全部楼层
不明觉力。。。
一直努力就很好。
回复 支持 反对

使用道具 举报

0

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
165
金钱
165
注册时间
2012-4-25
在线时间
10 小时
发表于 2013-12-3 15:00:27 | 显示全部楼层
不懂。。。。。。。。。。
QQ:747764222?可接项目 和 毕设等
? 可以出售各种LED灯,以及控制方案。
? ? LED灯已经出口到全球各地,控制方案也很有经验。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2014-1-16
在线时间
0 小时
发表于 2014-6-1 19:13:22 | 显示全部楼层
这个模糊控制的例子
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-23 23:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表