单片机PID控制.doc
《单片机PID控制.doc》由会员分享,可在线阅读,更多相关《单片机PID控制.doc(7页珍藏版)》请在冰豆网上搜索。
经典PID调节,恒温控制。
2009-08-1120:
37#include
#include
structPID{
unsignedintSetPoint;//设定目标DesiredValue
unsignedintProportion;//比例常数ProportionalConst
unsignedintIntegral;//积分常数IntegralConst
unsignedintDerivative;//微分常数DerivativeConst
unsignedintLastError;//Error[-1]
unsignedintPrevError;//Error[-2]
unsignedintSumError;//SumsofErrors
};
structPIDspid;//PIDControlStructure
unsignedintrout;//PIDResponse(Output)
unsignedintrin;//PIDFeedback(Input)
sbitdata1=P1^0;
sbitclk=P1^1;
sbitplus=P2^0;
sbitsubs=P2^1;
sbitstop=P2^2;
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;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=1;/*释放DQ总线*/_nop_();_nop_();EA=1;}/***********************************************************写一字节数据子程序***********************************************************/voidwrite_byte(unsignedcharval){unsignedchari;unsignedchartemp;EA=0;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,开始读时序*/_nop_();_nop_();DQ=1;/*释放总线*/for(i=0;i<2;i++){}value_bit=DQ;EA=1;return(value_bit);}/***********************************************************读一字节数据子程序***********************************************************/unsignedcharread_byte(){unsignedchari,value=0;EA=0;for(i=0;i<8;i++){if(read_bit())/*读一字节数据,一个时序中读一次,并作移位处理*/value|=0x01<delay(4);/*延时80us以完成此次都时序,之后再读下一数据*/}EA=1;return(value);}/***********************************************************复位子程序***********************************************************/unsignedcharreset(){unsignedcharpresence;EA=0;DQ=0;/*拉低DQ总线开始复位*/delay(30);/*保持低电平480us*/DQ=1;/*释放总线*/delay(3);presence=DQ;/*获取应答信号*/delay(28);/*延时以完成整个时序*/EA=1;return(presence);/*返回应答信号,有芯片应答返回0,无芯片则返回1*/}/***********************************************************获取温度子程序***********************************************************/voidget_temper(){unsignedchari,j;do{i=reset();/*复位*/}while(i!=0);/*1为无反馈信号*/i=0xcc;/*发送设备定位命令*/write_byte(i);i=0x44;/*发送开始转换命令*/write_byte(i);delay(180);/*延时*/do{i=reset();/*复位*/}while(i!=0);i=0xcc;/*设备定位*/write_byte(i);i=0xbe;/*读出缓冲区内容*/write_byte(i);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;//当前微分pp->PrevError=pp->LastError;pp->LastError=Error;return(pp->Proportion*Error//比例项+pp->Integral*pp->SumEror//积分项+pp->Derivative*dError);//微分项}/***********************************************************温度比较处理子程序***********************************************************/compare_temper(){unsignedchari;if(set_temper>temper){if(set_temper-temper>1)
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=1;/*释放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=0;/*拉低DQ,开始读时序*/
DQ=1;/*释放总线*/
for(i=0;i<2;i++){}
value_bit=DQ;
return(value_bit);
读一字节数据子程序
unsignedcharread_byte()
unsignedchari,value=0;
for(i=0;i<8;i++)
if(read_bit())/*读一字节数据,一个时序中读一次,并作移位处理*/
value|=0x01<
delay(4);/*延时80us以完成此次都时序,之后再读下一数据*/
return(value);
复位子程序
unsignedcharreset()
unsignedcharpresence;
DQ=0;/*拉低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);/*延时*/
=0);
i=0xcc;/*设备定位*/
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;//当前微分
pp->PrevError=pp->LastError;
pp->LastError=Error;
return(pp->Proportion*Error//比例项
+pp->Integral*pp->SumEror//积分项
+pp->Derivative*dError);//微分项
温度比较处理子程序
compare_temper()
if(set_temper>temper)
if(set_temper-temper>1)
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1