温度pid控制.docx

上传人:b****5 文档编号:6916000 上传时间:2023-01-12 格式:DOCX 页数:21 大小:17.93KB
下载 相关 举报
温度pid控制.docx_第1页
第1页 / 共21页
温度pid控制.docx_第2页
第2页 / 共21页
温度pid控制.docx_第3页
第3页 / 共21页
温度pid控制.docx_第4页
第4页 / 共21页
温度pid控制.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

温度pid控制.docx

《温度pid控制.docx》由会员分享,可在线阅读,更多相关《温度pid控制.docx(21页珍藏版)》请在冰豆网上搜索。

温度pid控制.docx

温度pid控制

温度pid控制

#include"SST89x5x4.H"#include#include

#include

sbitdp1=P2^4;

sbitdp2=P2^5;

sbitdp3=P2^6;

sbitdp4=P2^7;//数码管位选

sbitkey1=P2^0;

sbitkey2=P2^1;

sbitkey3=P2^2;

sbitkey4=P2^3;//按键位选

sbitP13=P1^3;//控制端口

sbitP34=P3^4;//测温DQ

sbitP35=P3^5;//发声端口

chardplib[11]={0x018,0x07B,0x02C,0x029,0x04B,0x089,0x088,0x03B,0x08,0x09,0x0EF};//数

码管表

chardpbuf[4];//每个数码管显示的数字缓冲区

intt=0;//控制循环次数或标志位

ints0=0;//用于延时或循环或标志位

ints1=0;//用于延时或循环或标志位

unsignedcharacc=0;//用于对温度芯片的读写操作

inthigh_time,low_time,count=0;//占空比调节参数floattemper;

intTTL=1,huansuan,TH1Z1,TL1Z1,TH1Z0,TL1Z0;//用于脉宽调制

intsign=0;//sign为1,则小数点显示,否则小数点不显示intdnt=0;//用于位选挨个点亮

intcnt=0;//用于控制是否一直按着加键或者减键intshujua;//读出温度数据的高位

intshujub;//温度低位

intzancun=0;//临时数据存放

intwatchdog=0;//软件看门狗,无操作定时返回退出

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

PID类

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

structPID{

intSetPoint;//设定目标DesiredValue

intProportion;//比例常数ProportionalConst

intIntegral;//积分常数IntegralConst

intDerivative;//微分常数DerivativeConst

floatLastError;//Error[-1]

floatPrevError;//Error[-2]

floatSumError;//SumsofErrors};

structPIDspid;//PIDControlStructure

floatrout;//PIDResponse(Output)

floatrin;//PIDFeedback(Input)

voidkeyprogram();//键盘参数设置子程序

voidobserve();//运行中观察设置参数子程序

voidsettingmode();//选择要设定的参数子程序

voidaddmode();//参数加

voidsubmode();//参数减

voiddisplaysetting(intmode);//键盘操作时显示的设置

voidINIT18B20();//初始芯片

voidWRBYTE(unsignedchara);//写字

voidRDBYTE();//读字

voiddelay10ms(void);//10MS延时,用于显示2S

voidget_temper();//温度测量子程序

voidchange(inta,intb);//对读出数据处理,与汇编原理一样

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

T0中断服务程序

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

voidtimer0(void)interrupt1using2//T0中断

{

TH0=0xEE;

TL0=0x00;

dp2=dp4=dp3=dp1=1;

if(dnt>3)

{dnt=0;}

if((dnt==1)&&(sign==1))

P0=dplib[dpbuf[dnt]]&0XF7;

else{

P0=dplib[dpbuf[dnt]];

watchdog++;

}

switch(dnt++)

{

case0:

dp1=0;

break;

case1:

dp2=0;

break;

case2:

dp3=0;

break;

case3:

dp4=0;

}

}

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

T1中断服务程序

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

voidserve_T1()interrupt3using3//T1

{

if(TTL==1)

{

P13=1;

TH1=TH1Z1;

TL1=TL1Z1;

TTL=0;

}

else{

P13=0;

TH1=TH1Z0;

TL1=TL1Z0;

TTL=1;

}

if(count==9)

count=0;

elsecount++;

}

/*====================================================================

================================

初始化PID类

======================================================================

===============================*/

voidPIDInit(structPID*pp)

{

memset(pp,0,sizeof(structPID));

}

/*====================================================================

================================

PID计算部分

======================================================================

===============================*/

floatPIDCalc(structPID*pp,floatNextPoint){

floatdError,Error;

Error=pp->SetPoint-NextPoint;//偏差

pp->SumError+=Error;//积分

dError=pp->LastError-pp->PrevError;//当前微分

pp->PrevError=pp->LastError;

pp->LastError=Error;

if(abs(spid.SetPoint-temper)<0.5)

pp->SumError=0;

return(pp->Proportion*Error//比例

+pp->Integral*pp->SumError//积分项

+pp->Derivative*dError);//微分项

}

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

温度控制子程序

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

voidcontrol_temper()

{if(spid.SetPoint-temper>4)

{

high_time=high_time+100;//高电平份数累加

}

elseif(temper-spid.SetPoint>4)

{

high_time=high_time-110;//高电平份数累减

}

elseif(abs(temper-spid.SetPoint)<4)

{

rin=temper;

rout=PIDCalc(&spid,rin);//进入PID计算

high_time=high_time+rout;

}

if(high_time>=1000)//防止过热过冷

high_time=999;

if(high_time<0)

high_time=1;

low_time=1000-high_time;//得到低电平份数

huansuan=65536-high_time*46;//换算得到T1定时器初值

TH1Z1=(huansuan&0xFF00>>8);

TL1Z1=huansuan&0x00FF;

huansuan=65536-low_time*46;

TH1Z0=(huansuan&0xFF00>>8);

TL1Z0=huansuan&0x00FF;}

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

温度测量子程序

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

voidget_temper()

{

EA=0;

INIT18B20();

acc=0xCC;

WRBYTE(acc);

acc=0x44;

WRBYTE(acc);

INIT18B20();

acc=0xCC;

WRBYTE(acc);

acc=0xBE;

WRBYTE(acc);

RDBYTE();

shujub=(int)acc;

RDBYTE();

shujua=(int)acc;

change(shujua,shujub);

EA=1;

}

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

初始化DS18B20

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

voidINIT18B20(){

t=4;

P34=0;

s0=62;

for(s0;s0>0;s0--);//延时500us

P34=1;

CY=0;

s0=6;

while(t--)

{

while(s0--)

{

if(P34==1)

{

t=0;

s1=1;

break;

}

}

}

if(s1==1)

{

s0=111;

while(s0--)

{

CY=CY|P34;

}

}

}

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

向DS18B20写字

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

voidWRBYTE(unsignedchara)

{

t=8;

CY=0;

while(t--)

{

a=(a>>1);

P34=0;

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

P34=CY;

s0=3;

for(s0;s0>0;s0--);

P34=1;

}

}

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

向DS18B20读字

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

voidRDBYTE()

{acc=0;

t=8;

while(t--)

{

P34=0;

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

P34=1;

CY=P34;

_nop_();

_nop_();

_nop_();

_nop_();

s0=5;

for(s0;s0>0;s0--);

P34=1;

if(CY==1)

{

acc=acc|0x80;

if(t)

{

acc=(acc>>1);

}

}

elseif(t)

{

acc=(acc>>1);

}

}

}

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

处理从DS18B20上读到的数值子程序

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

voidchange(a,b)

{

intzheng;

intxiaoshu;

zheng=((shujua&(0x07))<<4)+((shujub&(0xF0))>>4);//处理整数,转换BCD

temper=zheng;

xiaoshu=shujub&0x0F;//处理小数,转换BCD

zancun=((xiaoshu*10)&0xF0);

temper=temper+(float)(zancun>>4)/10;

if(sign==1)

{

dpbuf[3]=zheng/100;

zheng=zheng%100;

dpbuf[2]=zheng/10;

zheng=zheng%10;

dpbuf[1]=zheng;

dpbuf[0]=(zancun>>4);

}

}

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

延时子程序

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

voiddelay10ms(void)//10ms

{

unsignedchari0,j0;

for(i0=20;i0>0;i0--)

for(j0=248;j0>0;j0--);

}

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

参数设定子程序

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

voidkeyprogram()

{

if(key1==0)//判断是否进入设置

{//A

delay10ms();

if(key1==0)//进入设置了

{

P13=0;

while(!

key1);

sign=0;//B

dpbuf[2]=spid.SetPoint/100;

zancun=(int)spid.SetPoint%100;

dpbuf[1]=zancun/10;

zancun=zancun%10;

dpbuf[0]=zancun;

dpbuf[3]=1;//从模式一开始选择

while

(1)

{

if(key2==0)//判断是否进行参数选择

{

settingmode();//参数选择子程序

}

if(key3==0)//判断是否进行参数加

{

addmode();//参数加子程序

}

if(key4==0)//判断是否进行参数减减

{

submode();//参数减子程序

}

if(key1==0)//判断是否进行参数加加

{

delay10ms();

if(key1==0)

{while(!

key1);

break;

}

}

if((key3==1)&&(key4==1))//

{

delay10ms();

if((key3==1)&&(key4==1))

cnt=0;

}

if(watchdog==2000)

{

watchdog=0;

break;

}

}

}//B

}//A

watchdog=0;

sign=1;

}

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

观察参数子程序

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

voidobserve()

{

if(key4==0)//判断是否进入设置

{//A

delay10ms();

if(key4==0)//进入设置了

{

while(!

key4);

sign=0;//B

dpbuf[2]=spid.SetPoint/100;

zancun=(int)spid.SetPoint%100;

dpbuf[1]=zancun/10;

zancun=zancun%10;

dpbuf[0]=zancun;

dpbuf[3]=1;//从模式一开始观察

while

(1)

{

if(key2==0)//判断是否进行参数选择

{

settingmode();//参数选择子程序

}

if(key4==0)//判断是否结束观察

{

delay10ms();

if(key4==0)

{while(!

key4);

break;

}

}

if(watchdog==2000)

{

watchdog=0;

break;

}

if(count==10)

{

get_temper();//温度测量子程序

control_temper();//温度控制子程序

}

}

}//B

}//A

sign=1;

watchdog=0;

}

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

设置模式子程序

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

voidsettingmode()

{

delay10ms();

if(key2==0)//进入了模式选择

{

while(!

key2);

if(++dpbuf[3]==5)

{

dpbuf[3]=1;

}

displaysetting

(1);

dpbuf[2]=zancun/100;

zancun=zancun%100;

dpbuf[1]=zancun/10;

zancun=zancun%10;

dpbuf[0]=zancun;

}

}

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

参数加子程序

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

voidaddmode()

{

delay10ms();

displaysetting

(1);

if(key3==0)

{

if(cnt==0)

{

t=70;

while((--t)&&(!

key3))

{delay10ms();}

if(t==0)

cnt++;

zancun++;

}

elseif(cnt<10)

{

cnt++;

t=30;

while(t--)

{delay10ms();}

zancun++;

}

elseif(cnt==19)

{cnt=19;

t=30;

while(t--)

{delay10ms();}

zancun+=100;

}

elseif(cnt>=10)

{

cnt++;

t=30;

while(t--)

{delay10ms();}

zancun+=10;

}

}

if(dpbuf[3]==1)

{

if(zancun>100)

zancun=30;

}

elseif(zancun>800)

zancun=0;

displaysetting

(2);}

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

参数减子程序

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

voidsubmode()

{

delay10ms();

displaysetting

(1);

if(key4==0)

{

if(cnt==0)

{

t=75;

while((--t)&&(!

key4))

{delay10ms();}

if(t==0)

cnt++;

zancun--;

}

elseif(cnt<10)

{

cnt++;

t=30;

while(t--)

{delay10ms();}

zancun--;

}

elseif(cnt==19)

{cnt=19;

t=30;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1