#include "STC_NEW_8051.h" #include "DS18B20.h" #include "intrins.h" #include "math.h" #include "string.h" #define uchar unsigned char #define uint unsigned int #define duan P0 #define wei P2 //温度PID定义 结构体 struct PID { unsigned int SetPoint; // 设定目标 unsigned int Proportion; // 比例常数 unsigned int Integral; // 积分常数 unsigned int Derivative; // 微分常数 unsigned int LastError; // Error[-1] unsigned int PrevError; // Error[-2] unsigned int SumError; // Sums of Errors }spid; //struct PID spid; // PID Control Structure unsigned int rout; // PID 响应输出 unsigned int rin; // PID 反馈输入 unsigned char set_temper=35; //设定温度值 uchar xuanze=0; //数码管变量定义 uchar k,i=0,j=0; //占空比显示定义 uint zhankb; //温度变量定义 uint wendu; uchar temper; //温度整数部分 uint s; //温度小数部分 //PWM变量定义 sbit output=P1^4; unsigned char high_time,low_time; unsigned char count=0; //外部中断按钮 sbit key0=P3^2; //P3^2外部中断0 sbit key1=P3^3; //P3^3外部中断1 //按键定义 sbit k1=P3^0; sbit k2=P3^1; sbit k3=P3^4; sbit k4=P3^5; uchar disnum[]={0,0,0,0,0,0,0,0,0,0}; uchar buf[8]={0,0,0,0,0,0,0,0}; uchar codedistable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00}; void delay(uint z) //延时1ms { uchar i,j; for(i=z;i>0;i--) for(j=110;j>0;j--); } void PIDInit(struct PID *pp) //初始化PID结构体 { memset(pp,0,sizeof(structPID)); // 赋值0 } unsigned int PIDCalc(struct PID *pp, unsigned intNextPoint) { unsignedint 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(void) { unsignedchar i; if(set_temper>temper) { if(set_temper-temper>2) { high_time=100; low_time=0; } else { for(i=0;i<10;i++) { temper=(read_temp())/100; rin=(read_temp())%100;// Read Input rout=PIDCalc(&spid,rin);// Perform PID Interation } 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++) { temper=(read_temp())/100; rin=(read_temp())%100;// Read Input rout=PIDCalc(&spid,rin);// Perform PID Interation } if(high_time<100) high_time=(unsignedchar)(rout/10000); else high_time=0; low_time=(100-high_time); } } } void main() { unsignedchar a,b,flag=1;//临时变量 ucharx=10,y=8,z=6; ucharkeynum=0; /********数码管变量初始化**********/ k=0x01; /********定时器初始化**********/ TMOD=0x11; // SCON=0x50; // PCON=0x00; TH1=63000>>8; TL1=63000%256; TH0=(65536-50000)>>8; TL0=(65536-50000)%256; // TH1=244; //波特率2400 // TL1=244; TR1=1; TR0=1; ET1=1; ET0=1; //外部中断初始化 EX0=1; EX1=1; IT0=1; IT1=1; EA=1; /********DS18B20变量初始化**********/ ds18b20(); delay1ms(5000); /********PWM变量初始化**********/ high_time=50; low_time=50; PIDInit (&spid ); // Initialize Structure 初始化结构体 spid.Proportion= 10; // Set PID Coefficients 设置PID系数 spid.Integral= 8; spid.Derivative=6; spid.SetPoint= 100; // Set PID Setpoint while(1) { buf[0]=x/10; buf[1]=x%10; buf[2]=17; buf[3]=y/10; buf[4]=y%10; buf[5]=17; buf[6]=z/10; buf[7]=z%10; ds18b20(); wendu=read_temp(); disnum[0]=wendu/1000; disnum[1]=wendu%1000/100; disnum[2]=wendu%100/10; // disnum[3]=wendu%10/1; //占空比数据显示 disnum[3]=high_time/100; disnum[4]=high_time/10%10; disnum[5]=high_time%10; //设置温度值显示 disnum[6]=set_temper/10; disnum[7]=set_temper%10; temper=(read_temp())/100; b=temper; if(flag==1) a=b; if(abs(a-b)>5) temper=a; else temper=b; a=temper; flag=0; if(k1==0) { delay(10); if(k1==0) { delay(10); while(!k1); xuanze++; if(xuanze==2) xuanze=0; } } if(xuanze==1) { if(k2==0) { delay(10); if(k2==0) { delay(10); while(!k2); keynum++; if(keynum==4) keynum=0; } } if(keynum==1) { if(k3==0) { delay(10); if(k3==0) { delay(10); while(!k3); x++; } } if(k4==0) { delay(10); if(k4==0) { delay(10); while(!k4); x--; } } } if(keynum==2) { if(k3==0) { delay(10); if(k3==0) { delay(10); while(!k3); y++; } } if(k4==0) { delay(10); if(k4==0) { delay(10); while(!k4); y--; } } } if(keynum==3) { if(k3==0) { delay(10); if(k3==0) { delay(10); while(!k3); z++; } } if(k4==0) { delay(10); if(k4==0) { delay(10); while(!k4); z--; } } } } else { spid.Proportion= x; //设置PID系数 spid.Integral= y; spid.Derivative=z; } compare_temper(); } } //T0中断函数,完成PWM输出 void timer0() interrupt 1 { TH0=(65536-10000)>>8; TL0=(65536-10000)%256; count++; if(count<=high_time) //对于实物是低电平导通加热 output=0; elseif(count<=100) output=1; else count=0; } void timer1() interrupt 3 { TH1=63000>>8; TL1=63000%256; wei=0; if(xuanze==0) { if(i==1) duan=distable[disnum]|0x80; else duan=distable[disnum]; } if(xuanze==1) { duan=distable[buf[j]]; } wei=k; i++; j++; k=k<<1; if(i==8) { i=0; k=0x01; } if(j==8) j=0; if(key0) { EX0=1; IE0=0; } if(key1) { EX1=1; IE1=0; } } void int0() interrupt 0 { EX0=0; set_temper++; if(set_temper>75) set_temper=75; } void int1() interrupt 2 { EX1=0; set_temper--; if(set_temper<30) set_temper=30; }
解释温度ERROR偏差为什么是设定温度与温度小数部分做差?
|