新聞中心

        單片機(jī)PID溫控源代碼

        作者: 時(shí)間:2012-08-18 來(lái)源:網(wǎng)絡(luò) 收藏
        /*=============================================
        CopyLeft(CL) FORVERE Wjj
        All rights NOT reserved
        版權(quán)所無(wú),翻版不究,但請(qǐng)保留此處信息
        http://blog.sina.com.cn/u/2150397142
        any problem or suggestion mail to: 15258297408@163.com
        *******************************************/
        *文件名:PID_control
        *文件說(shuō)明:源代碼,采用PID算法處理的溫控模擬系統(tǒng) ,ADC0809采集數(shù)據(jù),IN4148為溫度傳感器
        *版本: The final version
        *芯片:
        *晶振: (外)內(nèi)部12MHz晶振
        *作者: Wang Jian Jun
        *日期: 2010年5月27日
        *編譯環(huán)境: keil3+proteus7
        *結(jié)果: 實(shí)物測(cè)試通過(guò),溫度維持在33℃-35℃
        *說(shuō)明: 采用PID算法處理的溫控模擬系統(tǒng) ,ADC0809采集數(shù)據(jù),IN4148為溫度傳感器,LCD顯示

        ========================================*/
        #includereg51.h> //加載C51核心庫(kù)文件
        #includeintrins.h> //加載應(yīng)用型庫(kù)文件
        #include"config.h" //加載用戶自配置可文件,此處未給出
        #define N0 40536
        #define nop() _nop_()
        #define uchar unsigned char
        #define uint unsigned int //以上宏定義,方便寫(xiě)代碼

        /*程序中變量 數(shù)組定義*/
        uchar idata table[]={"Real-time Temp:"}; //第一行顯示"Real-time Temp:"
        uchar idata table1[5];
        uchar data1;
        uchar kp;
        uchar ki;
        uchar kd; //以上為PID算法的比例,積分,微分系數(shù)
        uint t,hightime,count; //占空比調(diào)節(jié)參數(shù)
        uint rltemp,settemp=350;
        int e1,e2,e3,duk,uk;

        /*引腳定義*/
        sbit EOC=P2^6;
        sbit OE=P2^5;
        sbit START=P2^7;
        sbit lcden=P3^2;
        sbit lcdrw=P3^1;
        sbit lcdrs=P3^0;
        sbit pwm=P3^3;

        /******************************
        延時(shí)子程序
        *******************************/
        void delay(uint z)
        {
        uint x,y;
        for(x=z;x>0;x--)
        for(y=29;y>0;y--);
        }

        /******************************
        LCD忙檢測(cè)
        *******************************/
        bit lcd_busy()
        {
        bit result;
        lcdrw = 1;
        lcdrs = 0;
        lcden = 1;
        nop();nop();nop();nop();
        result = (bit)(P00x80);
        lcden = 0;
        return(result);
        }

        /******************************
        LCD寫(xiě)命令子程序
        *******************************/
        void write_com(uchar com)
        {
        while(lcd_busy());//忙等待
        lcdrs = 0;
        lcdrw = 0;
        P1 = com;
        delay(5);
        lcden = 1;
        delay(5);
        lcden = 0;
        }

        /******************************
        LCD寫(xiě)數(shù)據(jù)子程序
        *******************************/
        void write_data(uchar date)
        {
        while(lcd_busy()); //忙等待
        lcdrs = 1;
        lcdrw = 0;
        P1=date;
        delay(5);
        lcden = 1;
        delay(5);
        lcden = 0;
        }

        /******************************
        LCD初始化
        *******************************/
        void lcd_init()
        {
        lcden = 0;
        write_com(0x38);
        delay(5);
        write_com(0x0f);
        delay(5);
        write_com(0x06);
        delay(5);
        write_com(0x01);
        delay(5);
        write_com(0x80);
        delay(5);
        write_com(0x01);
        }

        /******************************
        定時(shí)器初始化
        *******************************/
        void time_init()
        {
        EA = 1;
        ET0 = 1;
        ET1 = 1;
        TR0 = 1;
        TR1 = 1;
        TMOD = 0x11;
        TH0 = N0/256;
        TL0 = N0%256;
        TH1 = 0X3C;
        TL1 = 0XB0;
        }

        /******************************
        PID算法系數(shù)設(shè)置
        *******************************/
        void Pid_init()
        {
        hightime= 0;
        e1 = 0;
        e2 = 0;
        e3 = 0;
        kp = 10;
        ki = 5;
        kd = 5;
        }

        /******************************
        溫度比較 PID算法
        *******************************/
        void pid_ys()
        {
        if(rltempsettemp) // 如果實(shí)際溫度小于設(shè)定值
        {
        if(settemp-rltemp>20) // 如果相差2度
        {
        hightime=100; //全速加熱
        }
        else //否則運(yùn)行PID算法進(jìn)行平滑加熱
        {
        e1 = settemp-rltemp;
        duk=(kp*(e1-e2)+ki*e1+kd*(e1-e2*2+e3))/10;
        uk = uk+duk;
        if(uk>100)
        uk = 100;
        else if(uk-100)
        uk = -100;
        if(uk0)
        {
        hightime=-uk;
        }
        else
        {
        hightime=uk;
        }
        e3 = e2;
        e2 = e1;
        }
        }
        if(rltemp>=settemp) // 如果實(shí)際溫度大于設(shè)定值
        {
        if(rltemp-settemp>0) //只要實(shí)際溫度與設(shè)定值有偏差
        {
        hightime=0; //停止加熱
        }
        else //其他情況運(yùn)行PID算法,但參數(shù)與前面的剛好相反
        {
        e1 = rltemp-settemp;
        duk=(kp*(e1-e2)+ki*e1+kd*(e1-e2*2+e3))/10;
        uk = uk+duk;
        if(uk>100)
        uk = 100;
        else if(uk-100)
        uk = -100;
        if(uk0)
        {
        hightime=100-(-uk);
        }
        else
        {
        hightime=100-uk;
        }
        e3 = e2;
        e2 = e1;
        }
        }

        }

        /******************************
        主函數(shù)
        *******************************/
        void main()
        {
        uint i;
        time_init();//定時(shí)器初始化
        Pid_init(); // PID初始化
        lcd_init(); // LCD初始化
        table1[5]=0x43;
        table1[4]=0xdf;
        table1[2]=0x2e; //小數(shù)點(diǎn) 攝氏度符號(hào)ASCII碼
        for(i=0;i15;i++) //帶循環(huán)第一行顯示"Real-time Temp:"
        {
        write_data(table[i]);
        delay(20);
        }
        while(1)
        {
        t=data1*196/100;
        table1[3]=(t%100)%10+0x30;
        table1[1]=(t%100)/10+0x30;
        table1[0]=t/100+0x30; //以上溫度數(shù)據(jù)轉(zhuǎn)化
        rltemp = t; //給PID算法裝載實(shí)際值
        write_com(0x80+0x45);//寫(xiě)LCD第二行的初地址
        for(i=0;i6;i++) //該循環(huán)顯示溫度值
        {
        write_data(table1[i]);
        delay(20);
        }
        pid_ys();//運(yùn)行溫度比較 PID算法
        }
        }

        /******************************
        溫度采集轉(zhuǎn)換的定時(shí)中斷
        0.5s刷新一次數(shù)據(jù)
        *******************************/
        void timer0() interrupt 1
        {
        uint j;
        j++;
        if(j==20)
        {
        OE = 0;
        START = 0;
        _nop_();
        START = 1;
        _nop_();
        START = 0;
        while(EOC==0);
        OE = 1;
        _nop_();
        data1 = P0;
        _nop_();
        OE = 0;
        j = 0;
        }
        TH0=N0/256;
        TL0=N0%256;
        }

        /******************************
        PWM波輸出的定時(shí)中斷
        *******************************/
        void timer1() interrupt 3
        {
        if(++count=(hightime))
        pwm=0;
        else if(count=100)
        {
        pwm=1;
        }
        else
        count=0;
        TH1=0x3c;
        TL1=0xb0;
        }

        /*==============================end of file=======================================*/


        關(guān)鍵詞: 單片機(jī) PID溫控 STC89C52RC

        評(píng)論


        相關(guān)推薦

        技術(shù)專(zhuān)區(qū)

        關(guān)閉
        主站蜘蛛池模板: 镶黄旗| 咸阳市| 类乌齐县| 云和县| 石棉县| 梧州市| 建昌县| 城固县| 安吉县| 独山县| 西丰县| 佛坪县| 克拉玛依市| 平邑县| 阳东县| 江油市| 新竹市| 绥芬河市| 麻栗坡县| 庄河市| 四平市| 大安市| 临泉县| 五莲县| 莆田市| 平潭县| 永年县| 沭阳县| 万全县| 富蕴县| 舟曲县| 上林县| 古田县| 徐水县| 双江| 石台县| 什邡市| 宁陕县| 鄂伦春自治旗| 田东县| 永善县|