<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 51 溫度PID經(jīng)典算法

          51 溫度PID經(jīng)典算法

          作者: 時間:2016-11-11 來源:網(wǎng)絡 收藏
          #include51.h>
          #include
          #include
          #include
          structPID{
          unsignedintSetPoint;//設定目標DesiredValue
          unsignedintProportion;//比例常數(shù)ProportionalConst
          unsignedintIntegral;//積分常數(shù)IntegralConst
          unsignedintDerivative;//微分常數(shù)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;//占空比調(diào)節(jié)參數(shù)
          unsignedcharset_temper=35;
          unsignedchartemper;
          unsignedchari;
          unsignedcharj=0;
          unsignedints;
          /***********************************************************
          延時子程序,延時時間以12M晶振為準,延時時間為30us×time
          ***********************************************************/
          voiddelay(unsignedchartime)
          {
          unsignedcharm,n;
          for(n=0;n for(m=0;m<2;m++){}
          }
          /***********************************************************
          寫一位數(shù)據(jù)子程序
          ***********************************************************/
          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;
          }
          /***********************************************************
          寫一字節(jié)數(shù)據(jù)子程序
          ***********************************************************/
          voidwrite_byte(unsignedcharval)
          {
          unsignedchari;
          unsignedchartemp;
          EA=0;
          TR0=0;
          for(i=0;i<8;i++)/*寫一字節(jié)數(shù)據(jù),一次寫一位*/
          {
          temp=val>>i;/*移位操作,將本次要寫的位移到最低位*/
          temp=temp&1;
          write_bit(temp);/*向總線寫該位*/
          }
          delay(7);/*延時120us后*/
          //TR0=1;
          EA=1;
          }
          /***********************************************************
          讀一位數(shù)據(jù)子程序
          ***********************************************************/
          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);
          }
          /***********************************************************
          讀一字節(jié)數(shù)據(jù)子程序
          ***********************************************************/
          unsignedcharread_byte()
          {
          unsignedchari,value=0;
          EA=0;
          for(i=0;i<8;i++)
          {
          if(read_bit())/*讀一字節(jié)數(shù)據(jù),一個時序中讀一次,并作移位處理*/
          value|=0x01<delay(4);/*延時80us以完成此次都時序,之后再讀下一數(shù)據(jù)*/
          }
          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;/*發(fā)送設備定位命令*/
          write_byte(i);
          i=0x44;/*發(fā)送開始轉(zhuǎn)換命令*/
          write_byte(i);
          delay(180);/*延時*/
          do
          {
          i=reset();/*復位*/
          }while(i!=0);
          i=0xcc;/*設備定位*/
          write_byte(i);
          i=0xbe;/*讀出緩沖區(qū)內(nèi)容*/
          write_byte(i);
          j=read_byte();
          i=read_byte();
          i=(i<<4)&0x7f;
          s=(unsignedint)(j&0x0f); //得到小數(shù)部分
          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;//當前微分
          pp->PrevError=pp->LastError;
          pp->LastError=Error;
          return(pp->Proportion*Error//比例項
          +pp->Integral*pp->SumError//積分項
          +pp->Derivative*dError);//微分項
          }
          /***********************************************************
          溫度比較處理子程序
          ***********************************************************/
          voidcompare_temper()
          {
          unsignedchari;
          if(set_temper>temper)//是否設置的溫度大于實際溫度
          {
          if(set_temper-temper>1) //設置的溫度比實際的溫度是否是大于1度
          {
          high_time=100; //如果是,則全速加熱
          low_time=0;
          }
          else //如果是在1度范圍內(nèi),則運行PID計算
          {
          for(i=0;i<10;i++)
          {
          get_temper(); //獲取溫度
          rin=s;//ReadInput
          rout=PIDCalc(&spid,rin);//PerformPIDInteration
          }
          if(high_time<=100)
          high_time=(unsignedchar)(rout/800);
          else
          high_time=100;
          low_time=(100-high_time);
          }
          }
          elseif(set_temper<=temper)
          {
          if(temper-set_temper>0)
          {
          high_time=0;
          low_time=100;
          }
          else
          {
          for(i=0;i<10;i++)
          {
          get_temper();
          rin=s;//ReadInput
          rout=PIDCalc(&spid,rin);//PerformPIDInteration
          }
          if(high_time<100)
          high_time=(unsignedchar)(rout/10000);
          else
          high_time=0;
          low_time=(100-high_time);
          }
          }
          //else
          //{}
          }
          /*****************************************************
          T0中斷服務子程序,用于控制電平的翻轉(zhuǎn),40us*100=4ms周期
          ******************************************************/
          voidserve_T0()interrupt1using1
          {
          if(++count<=(high_time))
          output=1;
          elseif(count<=100)
          {
          output=0;
          }
          else
          count=0;
          TH0=0x2f;
          TL0=0xe0;
          }
          /*****************************************************
          串行口中斷服務程序,用于上位機通訊
          ******************************************************/
          voidserve_sio()interrupt4using2
          {
          /*EA=0;
          RI=0;
          i=SBUF;
          if(i==2)
          {
          while(RI==0){}
          RI=0;
          set_temper=SBUF;
          SBUF=0x02;
          while(TI==0){}
          TI=0;
          }
          elseif(i==3)
          {
          TI=0;
          SBUF=temper;
          while(TI==0){}
          TI=0;
          }
          EA=1;*/
          }
          voiddisp_1(unsignedchardisp_num1[6])
          {
          unsignedcharn,a,m;
          for(n=0;n<6;n++)
          {
          //k=disp_num1[n];
          for(a=0;a<8;a++)
          {
          clk=0;
          m=(disp_num1[n]&1);
          disp_num1[n]=disp_num1[n]>>1;
          if(m==1)
          data1=1;
          else
          data1=0;
          _nop_();
          clk=1;
          _nop_();
          }
          }
          }
          /*****************************************************
          顯示子程序
          功能:將占空比溫度轉(zhuǎn)化為單個字符,顯示占空比和測得到的溫度
          ******************************************************/
          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;
          else
          disp_num[0]=0x60;
          k=k%100;
          disp_num[1]=number[k/10];
          disp_num[2]=number[k%10];
          k=temper;
          k=k%100;
          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;
          TH0=0x2f;
          TL0=0x40;
          SCON=0x50;
          PCON=0x00;
          TH1=0xfd;
          TL1=0xfd;
          PS=1;
          EA=1;
          EX1=0;
          ET0=1;
          ES=1;
          TR0=1;
          TR1=1;
          high_time=50;
          low_time=50;
          PIDInit(&spid);//InitializeStructure
          spid.Proportion=10;//SetPIDCoefficients比例常數(shù)ProportionalConst
          spid.Integral=8;//積分常數(shù)IntegralConst
          spid.Derivative=6;//微分常數(shù)DerivativeConst
          spid.SetPoint=100;//SetPIDSetpoint設定目標DesiredValue
          while(1)
          {
          if(plus==0)
          {
          EA=0;
          for(a=0;a<5;a++)
          for(b=0;b<102;b++){}
          if(plus==0)
          {
          set_temper++;
          flag=0;
          }
          }
          elseif(subs==0)
          {
          for(a=0;a<5;a++)
          for(b=0;a<102;b++){}
          if(subs==0)
          {
          set_temper--;
          flag=0;
          }
          }
          elseif(stop==0)
          {
          for(a=0;a<5;a++)
          for(b=0;b<102;b++){}
          if(stop==0)
          {
          flag=0;
          break;
          }
          EA=1;
          }
          get_temper();
          b=temper;
          if(flag_2==1)
          a=b;
          if((abs(a-b))>5)
          temper=a;
          else
          temper=b;
          a=temper;
          flag_2=0;
          if(++count1>30)
          {
          display();
          count1=0;
          }
          compare_temper();
          }
          TR0=0;
          z=1;
          while(1)
          {
          EA=0;
          if(stop==0)
          {
          for(a=0;a<5;a++)
          for(b=0;b<102;b++){}
          if(stop==0)
          disp_1(phil);
          //break;
          }
          EA=1;
          }
          }


          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();