一个实用的单片机PID方式控温实例讲课讲稿

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一个实用的单片机PID方式控温实例

§1:基本情况

本例中控制对象是一款小型专用工业烘箱

要求恒温范围:室温--300℃

恒温精度:±1℃

(其它指标略)

§2:控制器硬件

(参考原理图)

①.单片机采用(C51系列)TI公司的MCS1210Y4(内部有8通道24位AD转换器)串行口在线编程

②.前向通道温度信号(来自烘箱的Pt100电阻信号)经INA118放大送入AD

通道CH0

③.后向通道 I/O口驱动光耦MOC-3061,再驱动大功率双向可控硅输出

④.键盘 up 递增按钮和down 递减按钮,设置目标温度

⑤.LED(3位)显示温度值(软件切换显示目标温度或采样温度)

⑥.电源 +5V单电源

§3:软件介绍(由C语言编写)

①.流程采样当前温度--PID运算--PWM(占空比式)输出

②.温度采样

采样周期是一个很重要的参数

其确定取决于烘箱的固有响应特性参数(比如纯滞后时间θ以及

响应时间常数τ)一般值在4--20秒之间(例中取16秒)

③.PID运算

每采样一次之后进行一次PID运算,得到一个输出量,供输出函数调用.

为了下面叙述方便先定义几个变量

定义: T_target 表示目标温度

T_real 表示当前温度

T_diff 表示当前温差并且T_diff=T_target-T_real

PID运算表达式如下

PWM_OUT=P_OUT+I_OUT+D_OUT+P_H;(求代数和)

其中 P_OUT=KP*(T_diff)

称为比例项,KP是比例系数,比例项的作用是纠正偏差.

比例项输出等于比例系数乘当前温差

(原理图)

I_OUT=KI*∑(diff)

称为积分项,KI是积分系数,积分项用于消除系统稳态误差

∑(diff)含义是由当前算起前面N次采样温差的和(例中N取20)

D-_OUT=KD*Δdiff

称为微分项,KD是微分系数,

微分项用于减小系统超调量,增加系统稳定性.

(Δdiff=当前温差-上次温差)

P_H=KC*(T_target)

称为维持功率项,达温后(其它项均趋于0)此项起抵消散热维持温度的作用,可增加系统稳定性.

KC是维持功率系数

如果约定满功率值为100,停止输出功率值为0 那末PWM_OUT的取值范围就确定为0--100主要是为了后面编制输出函数时方便简明,直接调用PWM_OUT作为输出占空比的百分数)

后面整定系数时就要兼顾PWM_OUT的取值范围

§4.源程序(部分)

#define KP 3.0 //比例系数

#define KI 0.3 //积分系数

#define KD 200.0 //微分系数

#define KC 0.1 //维持功率系数

#define T_c 16 //采样周期(单位:秒)

sbit pid_port=P3^5; //控制输出端口

float T_target=0; //目标温度

float T_real=0; //当前温度

float PWM=0; //输出控制量

bit read_AD_enable=0; //PID运算允许标志位

//T0定时器初始化

void Timer0_Init()

{

TMOD|=0x01;

TF0 =0;

TR0 =1;

IE |=0x02;

}

//读取AD 转换值并刻度

void read_AD(void)

{

int delta_ad;

unsigned char ad[3];

ad[0]=ADRESH;

ad[1]=ADRESM;

ad[2]=ADRESL;

delta_ad=ad[0]*0x100+ad[1]-0x23cb;

if(delta_ad<=0)delta_ad=0;

T_real=(float)delta_ad/70;

}

//*--------PID运算函数

void pid(void)

{

static float diff[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; static float sum_diff=0; //∑(diff)

static int curr_=0;

float p_out,i_out,d_out,temp;

float pwm_0;

temp=diff[curr_];

if(curr_+1>=20)curr_=0;

else curr_+=1;

sum_diff-=diff[curr_];

diff[curr_]=T_target-T_real;

sum_diff+=diff[curr_];

p_out=KP*diff[curr_]; //比例项输出

i_out=KI*sum_diff; //积分项输出

d_out=KD*(diff[curr_]-temp); //微分项输出

pwm_0=KC*T_target; //维持功率项

if(i_out>100)i_out=100; //积分分离

if(i_out<-100)i_out=-100;

PWM=p_out+i_out+d_out+pwm_0; //总输出量

if(PWM<0)PWM=0;

else if(PWM>=100)PWM=100;

}

// 输出函数

void PWM_OUT(float PWM)

{

static unsigned char t=1; //t=(1--100)周期为4秒

unsigned char limit; //pid_value输出百分比

limit=(unsigned char)PWM;

if(t<=limit)pid_port=0; //加热

else pid_port=1; //停止加热

t++;

if(t>100)t=1;

相关文档
最新文档