pid温度参数整定Word文件下载.docx
《pid温度参数整定Word文件下载.docx》由会员分享,可在线阅读,更多相关《pid温度参数整定Word文件下载.docx(17页珍藏版)》请在冰豆网上搜索。
sbitoutput=P3^4;
sbitDQ=P3^3;
unsignedcharflag,flag_1=0;
unsignedcharhigh_time,low_time,count=0;
//占空比调节参数
unsignedcharset_temper=35;
unsignedchartemper;
unsignedchari;
unsignedcharj=0;
unsignedints;
/***********************************************************
延时子程序,延时时间以12M晶振为准,延时时间为30us×
time
***********************************************************/
voiddelay(unsignedchartime)
{
unsignedcharm,n;
for(n=0;
n<
time;
n++)
for(m=0;
m<
2;
m++){}
}
写一位数据子程序
voidwrite_bit(unsignedcharbitval)
EA=0;
DQ=0;
/*拉低DQ以开始一个写时序*/
if(bitval==1)
_nop_();
DQ=1;
/*如要写1,则将总线置高*/
delay(5);
/*延时90us供DA18B20采样*/
/*释放DQ总线*/
EA=1;
写一字节数据子程序
voidwrite_byte(unsignedcharval)
unsignedchartemp;
/*关中断*/
TR0=0;
for(i=0;
i<
8;
i++)/*写一字节数据,一次写一位*/
temp=val>
>
i;
/*移位操作,将本次要写的位移到最低位*/
temp=temp&
1;
write_bit(temp);
/*向总线写该位*/
delay(7);
/*延时120us后*/
//TR0=1;
/*开中断*/
读一位数据子程序
unsignedcharread_bit()
unsignedchari,value_bit;
/*拉低DQ,开始读时序*/
/*释放总线*/
i++){}
value_bit=DQ;
return(value_bit);
读一字节数据子程序
unsignedcharread_byte()
unsignedchari,value=0;
i++)
if(read_bit())/*读一字节数据,一个时序中读一次,并作移位处理*/
value|=0x01<
<
delay(4);
/*延时80us以完成此次都时序,之后再读下一数据*/
return(value);
复位子程序
unsignedcharreset()
unsignedcharpresence;
/*拉低DQ总线开始复位*/
delay(30);
/*保持低电平480us*/
delay(3);
presence=DQ;
/*获取应答信号*/
delay(28);
/*延时以完成整个时序*/
return(presence);
/*返回应答信号,有芯片应答返回0,无芯片则返回1*/
获取温度子程序
voidget_temper()
unsignedchari,j;
do
i=reset();
/*复位*/
}while(i!
=0);
/*1为无反馈信号*/
i=0xcc;
/*发送设备定位命令*/
write_byte(i);
i=0x44;
/*发送开始转换命令*/
delay(180);
/*延时*/
/*设备定位*/
i=0xbe;
/*读出缓冲区内容*/
j=read_byte();
i=read_byte();
i=(i<
4)&
0x7f;
s=(unsignedint)(j&
0x0f);
s=(s*100)/16;
j=j>
4;
temper=i|j;
/*获取的温度放在temper中*/
/*====================================================================================================
InitializePIDStructure
=====================================================================================================*/
voidPIDInit(structPID*pp)
memset(pp,0,sizeof(structPID));
PID计算部分
unsignedintPIDCalc(structPID*pp,unsignedintNextPoint)
unsignedintdError,Error;
Error=pp->
SetPoint-NextPoint;
//偏差
pp->
SumError+=Error;
//积分
dError=pp->
LastError-pp->
PrevError;
//当前微分
PrevError=pp->
LastError;
LastError=Error;
return(pp->
Proportion*Error//比例
+pp->
Integral*pp->
SumError//积分项
Derivative*dError);
//微分项
温度比较处理子程序
compare_temper()
if(set_temper>
temper)
if(set_temper-temper>
1)
high_time=100;
low_time=0;
else
10;
{get_temper();
rin=s;
//ReadInput
rout=PIDCalc(&
spid,rin);
//PerformPIDInteration
if(high_time<
=100)
high_time=(unsignedchar)(rout/800);
low_time=(100-high_time);
elseif(set_temper<
=temper)
if(temper-set_temper>
0)
high_time=0;
low_time=100;
100)
high_time=(unsignedchar)(rout/10000);
//else
//{}
/*****************************************************
T0中断服务子程序,用于控制电平的翻转,40us*100=4ms周期
******************************************************/
voidserve_T0()interrupt1using1
if(++count<
=(high_time))
output=1;
elseif(count<
output=0;
count=0;
TH0=0x2f;
TL0=0xe0;
串行口中断服务程序,用于上位机通讯
voidserve_sio()interrupt4using2
/*EA=0;
RI=0;
i=SBUF;
if(i==2)
while(RI==0){}
set_temper=SBUF;
SBUF=0x02;
while(TI==0){}
TI=0;
elseif(i==3)
SBUF=temper;
*/
voiddisp_1(unsignedchardisp_num1[6])
unsignedcharn,a,m;
6;
//k=disp_num1[n];
for(a=0;
a<
a++)
clk=0;
m=(disp_num1[n]&
1);
disp_num1[n]=disp_num1[n]>
if(m==1)
data1=1;
data1=0;
clk=1;
显示子程序
功能:
将占空比温度转化为单个字符,显示占空比和测得到的温度
voiddisplay()
unsignedcharcodenumber[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};
unsignedchardisp_num[6];
unsignedintk,k1;
k=high_time;
k=k%1000;
k1=k/100;
if(k1==0)
disp_num[0]=0;
disp_num[0]=0x60;
k=k%100;
disp_num[1]=number[k/10];
disp_num[2]=number[k%10];
k=temper;
disp_num[3]=number[k/10];
disp_num[4]=number[k%10]+1;
disp_num[5]=number[s/10];
disp_1(disp_num);
主程序
main()
unsignedcharz;
unsignedchara,b,flag_2=1,count1=0;
unsignedcharphil[]={2,0xce,0x6e,0x60,0x1c,2};
TMOD=0x21;
TL0=0x40;
SCON=0x50;
PCON=0x00;
TH1=0xfd;
TL1=0xfd;
PS=1;
EX1=0;
ET0=1;
ES=1;
TR0=1;
TR1=1;
high_time=50;
low_time=50;
PIDInit(&
spid);
//InitializeStructure
spid.Proportion=10;
//SetPIDCoefficients
spid.Integral=8;
spid.Derivative=6;
spid.SetPoint=100;
//SetPIDSetpoint
while
(1)
if(plus==0)
5;
for(b=0;
b<
102;
b++){}
set_temper++;
flag=0;
elseif(subs==0)
if(subs==0)
set_temper--;
elseif(stop==0)
if(stop==0)
break;
get_temper();
b=temper;
if(flag_2==1)
a=b;
if((abs(a-b))>
5)
temper=a;
temper=b;
a=temper;
flag_2=0;
if(++count1>
30)
display();
count1=0;
compare_temper();
z=1;
disp_1(phil);
//break;
//DS18b20子程序
#include<
REG52.H>
sbitDQ=P2^1;
//定义端口
typedefunsignedcharbyte;
typedefunsignedintword;
//延时
voiddelay(worduseconds)
{
for(;
useconds>
0;
useconds--);
}
//复位
byteow_reset(void)
bytepresence;
DQ=0;
//DQ低电平
delay(29);
//480us
DQ=1;
//DQ高电平
delay(3);
//等待
presence=DQ;
//presence信号
delay(25);
return(presence);
}//0允许,1禁止
//从1-wire总线上读取一个字节
byteread_byte(viod)
bytei;
bytevalue=0;
for(i=8;
i>
i--)
{
value>
=1;
delay
(1);
if(DQ)value|=0x80;
delay(6);
}
return(value);
//向1-wire总线上写一个字节
voidwrite_byte(charval)
i--)//一次写一个字节
DQ=val&
0x01;
delay(5);
val=val/2;
//读取温度
charRead_Temperature(void)
union{
bytec[2];
intx;
}temp;
ow_reset();
write_byte(0xcc);
write_byte(0xBE);
temp.c[1]=read_byte();
temp.c[0]=read_byte();
write_byte(0xCC);
write_byte(0x44);
returntemp.x/2;