51控制温度简单的PID算法Word格式.docx

上传人:b****5 文档编号:16450428 上传时间:2022-11-23 格式:DOCX 页数:14 大小:17.45KB
下载 相关 举报
51控制温度简单的PID算法Word格式.docx_第1页
第1页 / 共14页
51控制温度简单的PID算法Word格式.docx_第2页
第2页 / 共14页
51控制温度简单的PID算法Word格式.docx_第3页
第3页 / 共14页
51控制温度简单的PID算法Word格式.docx_第4页
第4页 / 共14页
51控制温度简单的PID算法Word格式.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

51控制温度简单的PID算法Word格式.docx

《51控制温度简单的PID算法Word格式.docx》由会员分享,可在线阅读,更多相关《51控制温度简单的PID算法Word格式.docx(14页珍藏版)》请在冰豆网上搜索。

51控制温度简单的PID算法Word格式.docx

//占空比调节参数

unsignedcharset_temper=35;

unsignedchartemper;

unsignedchari;

unsignedcharj=0;

unsignedints;

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

延时子程序,延时时间以12M晶振为准,延时时间为30us×

time

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

voiddelay(unsignedchartime)

{

unsignedcharm,n;

for(n=0;

nfor(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总线*/

_nop_();

EA=1;

写一字节数据子程序

voidwrite_byte(unsignedcharval)

unsignedchari;

unsignedchartemp;

TR0=0;

for(i=0;

i<

8;

i++)/*写一字节数据,一次写一位*/

temp=val>

>

i;

/*移位操作,将本次要写的位移到最低位*/

temp=temp&

1;

write_bit(temp);

/*向总线写该位*/

delay(7);

/*延时120us后*/

//TR0=1;

EA=1;

读一位数据子程序

unsignedcharread_bit()

unsignedchari,value_bit;

EA=0;

DQ=0;

/*拉低DQ,开始读时序*/

DQ=1;

/*释放总线*/

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));

//全部初始化为0

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);

//微分项

温度比较处理子程序

voidcompare_temper()

if(set_temper>

temper)//是否设置的温度大于实际温度

if(set_temper-temper>

1)//设置的温度比实际的温度是否是大于1度

{

high_time=100;

//如果是,则全速加热

low_time=0;

}

else//如果是在1度范围内,则运行PID计算

for(i=0;

10;

get_temper();

//获取温度

rin=s;

//ReadInput

rout=PIDCalc(&

spid,rin);

//PerformPIDInteration

if(high_time<

=100)

high_time=(unsignedchar)(rout/800);

else

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;

else

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;

for(n=0;

n<

6;

n++)

//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);

主程序

voidmain()

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比例常数ProportionalConst

spid.Integral=8;

//积分常数IntegralConst

spid.Derivative=6;

//微分常数DerivativeConst

spid.SetPoint=100;

//SetPIDSetpoint设定目标DesiredValue

while

(1)

if(plus==0)

for(a=0;

5;

for(b=0;

b<

102;

b++){}

set_temper++;

flag=0;

elseif(subs==0)

if(subs==0)

set_temper--;

flag=0;

elseif(stop==0)

for(b=0;

if(stop==0)

break;

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;

if(stop==0)

disp_1(phil);

//break;

}

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

当前位置:首页 > 高中教育 > 其它课程

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

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