在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 51單片機(jī)-溫度控制-PID算法-DS18B20-C語(yǔ)言

            51單片機(jī)-溫度控制-PID算法-DS18B20-C語(yǔ)言

            作者: 時(shí)間:2016-11-13 來(lái)源:網(wǎng)絡(luò) 收藏
            #include

            #include

            本文引用地址:http://www.biyoush.com/article/201611/316095.htm

            #include

            #include

            struct PID {

            unsigned int SetPoint; // 設(shè)定目標(biāo) Desired Value

            unsigned int Proportion; // 比例常數(shù) Proportional Const

            unsigned int Integral; // 積分常數(shù) Integral Const

            unsigned int Derivative; // 微分常數(shù) 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;//占空比調(diào)節(jié)參數(shù)

            unsigned char set_temper=35;

            unsigned char temper;

            unsigned char i;

            unsigned char j=0;

            unsigned int s;

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

            延時(shí)子程序,延時(shí)時(shí)間以12M晶振為準(zhǔn),延時(shí)時(shí)間為30us×time

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

            void delay(unsigned char time)

            {

            unsigned char m,n;

            for(n=0;n

            for(m=0;m<2;m++){}

            }

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

            寫(xiě)一位數(shù)據(jù)子程序

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

            void write_bit(unsigned char bitval)

            {

            EA=0;

            DQ=0; /*拉低DQ以開(kāi)始一個(gè)寫(xiě)時(shí)序*/

            if(bitval==1)

            {

            _nop_();

            DQ=1; /*如要寫(xiě)1,則將總線置高*/

            }

            delay(5); /*延時(shí)90us供DS18B20采樣*/

            DQ=1; /*釋放DQ總線*/

            _nop_();

            _nop_();

            EA=1;

            }

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

            寫(xiě)一字節(jié)數(shù)據(jù)子程序

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

            void write_byte(unsigned char val)

            {

            unsigned char i;

            unsigned char temp;

            EA=0;

            TR0=0;

            for(i=0;i<8;i++) /*寫(xiě)一字節(jié)數(shù)據(jù),一次寫(xiě)一位*/

            {

            temp=val>>i; /*移位操作,將本次要寫(xiě)的位移到最低位*/

            temp=temp&1;

            write_bit(temp); /*向總線寫(xiě)該位*/

            }

            delay(7); /*延時(shí)120us后*/

            // TR0=1;

            EA=1;

            }

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

            讀一位數(shù)據(jù)子程序

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

            unsigned char read_bit()

            {

            unsigned char i,value_bit;

            EA=0;

            DQ=0; /*拉低DQ,開(kāi)始讀時(shí)序*/

            _nop_();

            _nop_();

            DQ=1; /*釋放總線*/

            for(i=0;i<2;i++){}

            value_bit=DQ;

            EA=1;

            return(value_bit);

            }

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

            讀一字節(jié)數(shù)據(jù)子程序

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

            unsigned char read_byte()

            {

            unsigned char i,value=0;

            EA=0;

            for(i=0;i<8;i++)

            {

            if(read_bit()) /*讀一字節(jié)數(shù)據(jù),一個(gè)時(shí)序中讀一次,并作移位處理*/

            value|=0x01<

            delay(4); /*延時(shí)80us以完成此次都時(shí)序,之后再讀下一數(shù)據(jù)*/

            }

            EA=1;

            return(value);

            }

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

            復(fù)位子程序

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

            unsigned char reset()

            {

            unsigned char presence;

            EA=0;

            DQ=0; /*拉低DQ總線開(kāi)始復(fù)位*/

            delay(30); /*保持低電平480us*/

            DQ=1; /*釋放總線*/

            delay(3);

            presence=DQ; /*獲取應(yīng)答信號(hào)*/

            delay(28); /*延時(shí)以完成整個(gè)時(shí)序*/

            EA=1;

            return(presence); /*返回應(yīng)答信號(hào),有芯片應(yīng)答返回0,無(wú)芯片則返回1*/

            }

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

            獲取溫度子程序

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

            void get_temper()

            {

            unsigned char i,j;

            do

            {

            i=reset(); /*復(fù)位*/

            }while(i!=0); /*1為無(wú)反饋信號(hào)*/

            i=0xcc; /*發(fā)送設(shè)備定位命令*/

            write_byte(i);

            i=0x44; /*發(fā)送開(kāi)始轉(zhuǎn)換命令*/

            write_byte(i);

            delay(180); /*延時(shí)*/

            do

            {

            i=reset(); /*復(fù)位*/

            }while(i!=0);

            i=0xcc; /*設(shè)備定位*/

            write_byte(i);

            i=0xbe; /*讀出緩沖區(qū)內(nèi)容*/

            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; /*獲取的溫度放在temper中

            */

            }

            /*=========================================================================

            ===========================

            Initialize PID Structure

            ===========================================================================

            ==========================*/

            void PIDInit (struct PID *pp)

            {

            memset ( pp,0,sizeof(struct PID));

            }

            /*=========================================================================

            ===========================

            PID計(jì)算部分

            ===========================================================================

            ==========================*/

            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; // 當(dāng)前微分

            pp->PrevError = pp->LastError;

            pp->LastError = Error;

            return (pp->Proportion * Error // 比例項(xiàng)

            + pp->Integral * pp->SumEror // 積分項(xiàng)

            + pp->Derivative * dError); // 微分項(xiàng)

            }

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

            溫度比較處理子程序

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

            compare_temper()

            {

            unsigned char i;

            if(set_temper>temper)

            {

            if(set_temper-temper>1)

            {

            high_time=100;

            low_time=0;

            }

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

            // {}

            }

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

            T0中斷服務(wù)子程序,用于控制電平的翻轉(zhuǎn) ,40us*100=4ms周期

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

            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;

            }

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

            串行口中斷服務(wù)程序,用于上位機(jī)通訊

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

            void serve_sio() interrupt 4 using 2

            {

            /* EA=0;

            RI=0;

            i=SBUF;

            if(i==2)

            {

            while(RI==0){}

            RI=0;

            set_temper=SBUF;

            SBUF=0x02;

            while(TI==0){}

            TI=0;

            }

            else if(i==3)

            {

            TI=0;

            SBUF=temper;

            while(TI==0){}

            TI=0;

            }

            EA=1; */

            }

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

            }

            }

            }

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

            顯示子程序

            功能:將占空比溫度轉(zhuǎn)化為單個(gè)字符,顯示占空比和測(cè)得到的溫度

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

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

            }

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

            主程序

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

            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

            spid.Integral = 8;

            spid.Derivative =6;

            spid.SetPoint = 100; // Set PID Setpoint

            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;

            }

            }



            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉