注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
77554971的个人空间 https://home.eeworld.com.cn/space-uid-229832.html [收藏] [复制] [分享] [RSS]
日志

PID温度控制系统的设计_落叶★秋枫的空间

热度 4已有 2495 次阅读2010-11-30 10:34

PID是比例,积分,微分的缩写. 比例调节作用:是按比例反应系统的偏差,系统一旦出现了偏差,比例调节立即产生调节作用用以减少偏差。比例作用大,可以加快调节,减少误差,但是过大的比例,使系统的稳定性下降,甚至造成系统的不稳定。积分调节作用:是使系统消除稳态误差,提高无差度。因为有误差,积分调节就进行,直至无差,积分调节停止,积分调节输出一常值。积分作用的强弱取决与积分时间常数Ti,Ti越小,积分作用就越强。反之Ti大则积分作用弱,加入积分调节可使系统稳定性下降,动态响应变慢。积分作用常与另两种调节规律结合,组成PI调节器或PID调节器。微分调节作用:微分作用反映系统偏差信号的变化率,具有预见性,能预见偏差变化的趋势,因此能产生超前的控制作用,在偏差还没有形成之前,已被微分调节作用消除。因此,可以改善系统的动态性能。在微分时间选择合适情况下,可以减少超调,减少调节时间。微分作用对噪声干扰有放大作用,因此过强的加微分调节,对系统抗干扰不利。此外,微分反应的是变化率,而当输入没有变化时,微分作用输出为零。微分作用不能单独使用,需要与另外两种调节规律相结合,组成PD或PID控制器。

百度一搜最多还是理论上的说说,具体的PID控制我还不怎么明白的过来.总感觉PID用起来不难,真正和理论相结合解释的时候我很糊涂,看来多下点功夫研究PID.

下面我应一朋友的要求制作的PID温控系统,温度采用数码管显示.开机用按键设置好温度后才可以进行PID控制.

实物如下:

用到的材料有STC89C52 可泡水的DS18B20 4位共阳数码管 按键4个

原理图:

PCB图:

程序如下:

/***********************************************************************

PID温度控制程序

程序说明:

系统上电后显示 “--温度”

表示需要先设定温度才开始进行温度检测

温度设定完毕后程序才开始进行PID温控

***********************************************************************/

#include

#include

#include"DS18B20.H"

#include"PID.H"

#define uchar unsigned char

#define uint unsigned int

unsigned char code tab[]=

{

0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xBF

}

;

/*个位0~9的数码管段码*/

unsigned char code sao[]=

{

0x7f,0xbf,0xdf,0xef

}

;

//扫描码

uchar set=30,keyflag=1 ; //set初始化为30° keyflag为进入温度设定的标志位

//4个按键使用说明

sbit key_out=P1^0 ; //用于温度设定后的退出

sbit key_up=P1^1 ; //设定温度加

sbit key_down=P1^2 ; //设定温度减

sbit key_in=P1^3 ; //在程序的运行中如需要重新设定温度 按下此键才能进入设置模式并且此时是停在温度控制的,按下key_out键后才表示设定完毕

void Show_key();

/***********************************************************/

void delays(unsigned char k)

{

unsigned char i,j ;

for(i=0;i

for(j=0;j<50;j++);

}

/*********************************************************

//数码管显示函数

P0口 作为数据口

P2口的低四位作为扫描口

变量 x表示扫描

d表示是否要加小数点 为1是 为0不加

y表示传递的数值

*********************************************************/

LCD_disp_char(uchar x,bit d,uchar y)

{

P2=0XFF ;

P0=0xFF ;

if(d==0)

P0=tab[y];

else

P0=tab[y]&0x7f ; //与上0x7f表示是否要加小数点

P2=sao[x]; //打开扫描端号

}

/*********************************************************

按键扫描

*********************************************************/

void keyscan(void)

{

if(key_in==0) //按键进入函数

{

delays(10); //延时消抖 (以下同)

if(key_in==0)

{

while(key_in==0)

{

Show_key(); //如果一直按着键不放 就一直显示在当前状态 (以下同)

}

keyflag=1 ; //按键标志位

}

}

/***********************/

if(key_out==0) //按键退出

{

delays(10);

if(key_out==0)

{

while(key_out==0)

{

Show_key();

}

keyflag=0 ;

set_temper=set ;

}

}

/*************************/

if(key_up==0) //设定温度的加

{

delays(10);

if(key_up==0)

{

while(key_up==0)

{

Show_key();

}

if(keyflag==1)

{

set++;

if(set>90) //如果大于90°就不在加

set=90 ;

}

}

}

/*************************/

if(key_down==0) //温度设定的减

{

delays(10);

if(key_down==0)

{

while(key_down==0)

{

Show_key();

}

if(keyflag==1)

{

set--;

if(set<30) //温度减到30°时不在往下减

set=30 ;

}

}

}

}

/*********************************************************************

按键按下时的显示函数

***********************************************************************/

void Show_key()

{

output=1 ;

LCD_disp_char(3,0,10); //显示 -

delays(3);

LCD_disp_char(2,0,10); //显示- (表示温度设定 )

delays(3);

LCD_disp_char(1,0,set/10); //显示温度十位

delays(3);

LCD_disp_char(0,0,set%10); //显示温度个位

delays(3);

}

/*****************************************************************/

void main()

{

unsigned int tmp ;//声明温度中间变量

unsigned char counter=0 ;

PIDBEGIN(); //PID参数的初始化

output=1 ; //关闭继电器输出

while(1)

{

keyscan();

if(keyflag)

{

Show_key(); //显示温度设定

}

else

{

if(counter--==0)

{

tmp=ReadTemperature();//每隔一段时间读取温度值

counter=20 ;

}

LCD_disp_char(3,0,tmp/1000); //显示温度十位

delays(3);

LCD_disp_char(2,1,tmp/100%10); //显示温度个位

//显示小数点

delays(3);

LCD_disp_char(1,0,tmp/10%10); //显示温度小数后一位

delays(3);

LCD_disp_char(0,0,tmp%10);//显示温度小数后二位

delays(3);

P2=0XFF ;

P0=0xff ;

compare_temper(); //比较温度

}

}

}

/**********************************************************************************************************************************************/

//PID算法温控C语言2008-08-17 18:58

#ifndef _PID_H__

#define _PID_H__

#include

#include

#include

struct PID

{

unsigned int SetPoint ;

// 设定目标 Desired Value

unsigned int Proportion ;

// 比例常数 Proportional Const

unsigned int Integral ;

// 积分常数 Integral Const

unsigned int Derivative ;

// 微分常数 Derivative Const

unsigned int LastError ;

// Error[-1]

unsigned int PrevError ;

// Error[-2]

unsigned int SumError ;

// Sums of Errors

}

;

struct PID spid ;

// PID Control Structure

unsigned int rout ;

// PID Response (Output)

unsigned int rin ;

// PID Feedback (Input)

sbit output=P1^4;

unsigned char high_time,low_time,count=0 ;

//占空比调节参数

unsigned char set_temper ;

void PIDInit(struct PID*pp)

{

memset(pp,0,sizeof(struct PID)); //PID参数初始化全部设置为0

}

unsigned int PIDCalc(struct PID*pp,unsigned int NextPoint)

{

unsigned int dError,Error ;

Error=pp->SetPoint-NextPoint ;

// 偏差

pp->SumError+=Error ;

// 积分

dError=pp->LastError-pp->PrevError ;

// 当前微分

pp->PrevError=pp->LastError ;

pp->LastError=Error ;

//比例

//积分项

return(pp->Proportion*Error+pp->Integral*pp->SumError+pp->Derivative*dError);

// 微分项

}

/***********************************************************

温度比较处理子程序

***********************************************************/

void compare_temper()

{

unsigned char i ;

//EA=0;

if(set_temper>temper)

{

if(set_temper-temper>1)

{

high_time=100 ; //大于1°不进行PID运算

low_time=0 ;

}

else

{ //在1°范围内进行PID运算

for(i=0;i<10;i++)

{

//get_temper();

rin=s;

// Read Input

rout=PIDCalc(&spid,rin); //执行PID运算

// Perform PID Interation

}

if(high_time<=100) //限制最大值

high_time=(unsigned char)(rout/800);

else

high_time=100;

low_time=(100-high_time);

}

}

/****************************************/

else if(set_temper<=temper) //当实际温度大于设置温度时

{

if(temper-set_temper>0)//如果实际温度大于设定温度

{

high_time=0 ;

low_time=100 ;

}

else

{

for(i=0;i<10;i++)

{

//get_temper();

rin=s ;

// Read Input

rout=PIDCalc(&spid,rin);

// Perform PID Interation

}

if(high_time<100) //此变量是无符号字符型

high_time=(unsigned char)(rout/10000);

else

high_time=0 ;//限制不输出负值

low_time=(100-high_time);

//EA=1;

}

}

}

/*****************************************************

T0中断服务子程序,用于控制电平的翻转 ,40us*100=4ms周期

******************************************************/

void serve_T0()interrupt 1 using 1

{

if(++count<=(high_time))

output=0 ;

else if(count<=100)

{

output=1 ;

}

else

count=0 ;

TH0=0x2f ;

TL0=0xe0 ;

}

void PIDBEGIN()

{

TMOD=0x01 ;

TH0=0x2f ;

TL0=0x40 ;

EA=1 ;

ET0=1 ;

TR0=1 ;

high_time=50 ;

low_time=50 ;

PIDInit(&spid);

// Initialize Structure

spid.Proportion=10 ;

// Set PID Coefficients

spid.Integral=8 ;

spid.Derivative=6 ;

spid.SetPoint=100 ;

// Set PID Setpoint

}

#endif

限于篇幅 程序比较长还是分模块的,如需要的朋友留下Email 我看到了会发给你的!

发表评论 评论 (20 个评论)
回复 i了了 2010-11-30 15:01
感觉要学的东西还是挺多的啊···
回复 wps050 2011-5-7 09:42
给我一份啊wps050@163.com    谢谢啊
回复 wps050 2011-5-7 09:43
随便问一下high_time=(unsigned char)(rout/800);这条语句的数值是怎么计算抑或估算出来的啊,再次感谢
回复 吕成鹏 2011-5-8 11:08
我的设计是通信机房的自动温度控制系统设计。能用你的程序吗??我不太懂,你能发给我吗》??谢谢啊我的emai是765580857@qq.com。谢谢诶
回复 785xian 2011-8-29 20:02
很感谢……我的邮箱是bowen100800@126.com
回复 richchan 2011-10-17 14:12
非常好的pid实例。。。能给我一份吗goonccc@gmail.com,谢谢了
回复 j83746449 2011-11-15 16:48
很好呢。。很需要能给一份么594415537@qq.com 谢谢
回复 go_boy 2012-1-12 15:26
最近正在弄这方面的东西 ,看了以后帮助太大了 。程序和电路能给我一份吗?
16985719@qq.com
回复 mdq123 2012-7-7 12:42
自己再看看在学习学习吧,谢谢哈
回复 pengyanyun 2012-7-29 21:01
你好,能给我发一份吗?我的邮箱是742939848@qq.com。还有请问一下,在进行恒温控制时,使用模拟的PID好一些,还是数字的PID好些呢?
回复 1258140017 2013-2-1 12:58
能发给我一份吗?谢谢
回复 1258140017 2013-2-1 16:21
发个给我呗!谢了 我的邮箱1258140017@qq.com
回复 go_boy 2013-3-7 23:28
正在做pid的水温控制 ,硬件都做好了 功能也基本实现了 就差pid这一块了 ,给发一个程序吧,谢谢16985719@qq.com
回复 wangyifan 2013-4-2 16:33
发一份给我吧,jintanwzb@163.com,谢谢!
回复 chai110 2013-7-23 15:36
在搞温控系统,兄弟发一份312186728@qq.com
回复 hxs269095375 2013-7-30 09:43
不错啊,给我发一份呗,谢啦。邮箱:269095375@qq.com
回复 512581217 2014-3-18 22:40
很好,发份给我吧,急需   512581217@qq.com
回复 AT89C51王飞 2014-4-27 11:47
first_semon@163.com
回复 兔先森 2014-7-27 10:25
1208952982@qq.com
回复 良迹天涯 2014-9-28 22:48
你好,能不能发给我一下,非常感谢。1664428957@qq.com

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章