温度pid控制Word格式文档下载.docx
《温度pid控制Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《温度pid控制Word格式文档下载.docx(21页珍藏版)》请在冰豆网上搜索。
![温度pid控制Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2023-1/11/0cf4bba0-3af2-4f0a-87da-c6785c3071f2/0cf4bba0-3af2-4f0a-87da-c6785c3071f21.gif)
//占空比调节参数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;
case2:
dp3=0;
case3:
dp4=0;
T1中断服务程序
voidserve_T1()interrupt3using3//T1
if(TTL==1)
P13=1;
TH1=TH1Z1;
TL1=TL1Z1;
TTL=0;
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;
//当前微分
PrevError=pp->
LastError;
LastError=Error;
if(abs(spid.SetPoint-temper)<
0.5)
SumError=0;
return(pp->
Proportion*Error//比例
+pp->
Integral*pp->
SumError//积分项
Derivative*dError);
//微分项
温度控制子程序
voidcontrol_temper()
{if(spid.SetPoint-temper>
4)
high_time=high_time+100;
//高电平份数累加
elseif(temper-spid.SetPoint>
high_time=high_time-110;
//高电平份数累减
elseif(abs(temper-spid.SetPoint)<
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&
TL1Z0=huansuan&
}
温度测量子程序
voidget_temper()
EA=0;
INIT18B20();
acc=0xCC;
WRBYTE(acc);
acc=0x44;
acc=0xBE;
RDBYTE();
shujub=(int)acc;
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;
if(s1==1)
s0=111;
CY=CY|P34;
向DS18B20写字
voidWRBYTE(unsignedchara)
t=8;
a=(a>
1);
_nop_();
P34=CY;
s0=3;
向DS18B20读字
voidRDBYTE()
{acc=0;
_nop_();
CY=P34;
s0=5;
if(CY==1)
acc=acc|0x80;
if(t)
acc=(acc>
elseif(t)
处理从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>
延时子程序
voiddelay10ms(void)//10ms
unsignedchari0,j0;
for(i0=20;
i0>
i0--)
for(j0=248;
j0>
j0--);
参数设定子程序
voidkeyprogram()
if(key1==0)//判断是否进入设置
{//A
delay10ms();
if(key1==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)//判断是否进行参数加加
if(key1==0)
{while(!
if((key3==1)&
(key4==1))//
(key4==1))
cnt=0;
if(watchdog==2000)
watchdog=0;
}//B
}//A
sign=1;
观察参数子程序
voidobserve()
if(key4==0)//判断是否进入设置
if(key4==0)//进入设置了
key4);
//从模式一开始观察
if(key4==0)//判断是否结束观察
if(key4==0)
if(count==10)
get_temper();
control_temper();
//温度控制子程序
设置模式子程序
voidsettingmode()
if(key2==0)//进入了模式选择
key2);
if(++dpbuf[3]==5)
displaysetting
(1);
dpbuf[2]=zancun/100;
zancun=zancun%100;
参数加子程序
voidaddmode()
if(key3==0)
if(cnt==0)
t=70;
while((--t)&
(!
key3))
{delay10ms();
if(t==0)
cnt++;
zancun++;
elseif(cnt<
10)
t=30;
elseif(cnt==19)
{cnt=19;
zancun+=100;
elseif(cnt>
=10)
zancun+=10;
if(dpbuf[3]==1)
if(zancun>
100)
zancun=30;
elseif(zancun>
800)
zancun=0;
displaysetting
(2);
参数减子程序
voidsubmode()
t=75;
key4))
zancun--;