<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

        51單片機控制DS18B20測溫的PID溫控程序

        作者:未知   來源:不詳   點擊數:  更新時間:2014年07月31日   【字體:

        #include<reg51.h>

        #include<intrins.h>
        #include<math.h>
        #include<string.h>
         
        struct PID { 
        unsigned int SetPoint; // 設定目標 Desired Value 
        unsigned int Proportion; // 比例常數 Proportional Const 
        unsigned int Integral; // 積分常數 Integral Const 
        unsigned int Derivative; // 微分常數 Derivative Const 
        unsigned int LastError; // Error[-1] 
        unsigned int PrevError; // Error[-2] 
        unsigned int SumError; // Sums of Errors 
        }; 
        struct PID spid; // PID Control Structure 
        unsigned int rout; // PID Response (Output) 
        unsigned int rin; // PID Feedback (Input) 
        sbit data1=P1^0; 
        sbit clk=P1^1; 
        sbit plus=P2^0; 
        sbit subs=P2^1; 
        sbit stop=P2^2; 
        sbit output=P3^4; 
        sbit DQ=P3^3; 
        unsigned char flag,flag_1=0; 
        unsigned char high_time,low_time,count=0;//占空比調節參數 
        unsigned char set_temper=35; 
        unsigned char temper; 
        unsigned char i; 
        unsigned char j=0; 
        unsigned int s; 
         
        void delay(unsigned char time) 
             unsigned char m,n; 
             for(n=0;n
             for(m=0;m<2;m++){} 
         
        void write_bit(unsigned char bitval) 
          EA=0; 
          DQ=0; 
        if(bitval==1) 
          _nop_(); 
          DQ=1; 
         delay(5); 
         DQ=1; 
        _nop_(); 
        _nop_(); 
        EA=1; 
         
        void write_byte(unsigned char val) 
             unsigned char i; 
            unsigned char temp; 
            EA=0; 
            TR0=0; 
        for(i=0;i<8;i++) 
          temp=val>>i; 
          temp=temp&1; 
          write_bit(temp); 
          delay(7); 
        // TR0=1; 
          EA=1; 
         
        unsigned char read_bit() 
        unsigned char i,value_bit; 
        EA=0; 
        DQ=0; 
        _nop_(); 
        _nop_(); 
        DQ=1; 
        for(i=0;i<2;i++){} 
        value_bit=DQ; 
        EA=1; 
        return(value_bit); 
         
        unsigned char read_byte() 
        unsigned char i,value=0; 
        EA=0; 
        for(i=0;i<8;i++) 
        if(read_bit()) 
        value|=0x01<<i; 
        delay(4); 
        EA=1; 
        return(value); 
         
        unsigned char reset() 
        unsigned char presence; 
        EA=0; 
        DQ=0; 
        delay(30); 
        DQ=1; 
        delay(3); 
        presence=DQ; 
        delay(28); 
        EA=1; 
        return(presence); 
         
        void get_temper() 
        unsigned char i,j; 
        do 
           i=reset(); 
        }  while(i!=0); 
             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=(unsigned int)(j&0x0f);     //得到小數部分
           s=(s*100)/16; 
           j=j>>4; 
           temper=i|j; 
         
        void PIDInit (struct PID *pp) 
        memset ( pp,0,sizeof(struct PID));    //全部初始化為0
         
        unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint ) 
        unsigned int dError,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);                // 微分項 
         
        void compare_temper() 
        unsigned char i; 
        if(set_temper>temper)      //是否設置的溫度大于實際溫度
           if(set_temper-temper>1)  //設置的溫度比實際的溫度是否是大于1度
          { 
           high_time=100;      //如果是,則全速加熱
           low_time=0; 
          } 
               else  //如果是在1度范圍內,則運行PID計算
          { 
            for(i=0;i<10;i++) 
          { 
            get_temper();   //獲取溫度
             rin = s; // Read Input 
            rout = PIDCalc ( &spid,rin ); // Perform PID Interation 
          } 
            if (high_time<=100) 
              high_time=(unsigned char)(rout/800); 
            else 
                  high_time=100; 
              low_time= (100-high_time); 
          } 
        else if(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; // Read Input 
             rout = PIDCalc ( &spid,rin ); // Perform PID Interation 
           } 
             if (high_time<100) 
              high_time=(unsigned char)(rout/10000); 
               else 
              high_time=0; 
              low_time= (100-high_time); 
          } 
        // else 
        // {} 
         
        void serve_T0() interrupt 1 using 1 
        if(++count<=(high_time)) 
        output=1; 
        else if(count<=100) 
        output=0; 
        else 
        count=0; 
        TH0=0x2f; 
        TL0=0xe0; 
         
        void serve_sio() interrupt 4 using 2 
         
        void disp_1(unsigned char disp_num1[6]) 
        unsigned char n,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_(); 
         } 
         
        void display() 
        unsigned char code number[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6}; 
        unsigned char disp_num[6]; 
        unsigned int k,k1; 
        k=high_time; 
        k=k00; 
        k1=k/100; 
        if(k1==0) 
        disp_num[0]=0; 
        else 
        disp_num[0]=0x60; 
        k=k0; 
        disp_num[1]=number[k/10]; 
        disp_num[2]=number[k]; 
        k=temper; 
        k=k0; 
        disp_num[3]=number[k/10]; 
        disp_num[4]=number[k]+1; 
        disp_num[5]=number[s/10]; 
        disp_1(disp_num); 
         
        void main() 
        unsigned char z;
        unsigned char a,b,flag_2=1,count1=0; 
        unsigned char phil[]={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 );    // Initialize Structure 
        spid.Proportion = 10; // Set PID Coefficients  比例常數 Proportional Const 
        spid.Integral = 8;    //積分常數 Integral Const 
        spid.Derivative =6;   //微分常數 Derivative Const 
        spid.SetPoint = 100; // Set PID Setpoint 設定目標 Desired Value 
        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; 
          }
         } 
        else if(subs==0) 
          { 
        for(a=0;a<5;a++) 
        for(b=0;a<102;b++){} 
        if(subs==0) 
         set_temper--; 
         flag=0; 
          } 
        else if(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; 
        }
         
        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮