• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    單片機(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ù)專區(qū)

    關(guān)閉
    主站蜘蛛池模板: 息烽县| 普兰店市| 沙坪坝区| 广宁县| 乐至县| 乌审旗| 义乌市| 乌兰县| 宣城市| 乌兰察布市| 石棉县| 淳化县| 西丰县| 汉阴县| 南阳市| 高邑县| 汤阴县| 全州县| 西丰县| 南靖县| 开远市| 屯门区| 台江县| 甘孜县| 卢氏县| 敦化市| 循化| 五家渠市| 福贡县| 长泰县| 和田县| 皮山县| 牙克石市| 汤原县| 吉木萨尔县| 东安县| 林周县| 喜德县| 济宁市| 北票市| 玛纳斯县|