首页 温度pid控制

温度pid控制

举报
开通vip

温度pid控制温度pid控制 #include "SST89x5x4.H" #include #include #include sbit dp1=P2^4; sbit dp2=P2^5; sbit dp3=P2^6; sbit dp4=P2^7;//数码管位选 sbit key1=P2^0; sbit key2=P2^1; sbit key3=P2^2; sbit key4=P2^3;//按键位选 sbit P13=P1^3;//控制端口 sbit P34=P3^4;//测温DQ sbit P35=...

温度pid控制
温度pid控制 #include "SST89x5x4.H" #include #include #include sbit dp1=P2^4; sbit dp2=P2^5; sbit dp3=P2^6; sbit dp4=P2^7;//数码管位选 sbit key1=P2^0; sbit key2=P2^1; sbit key3=P2^2; sbit key4=P2^3;//按键位选 sbit P13=P1^3;//控制端口 sbit P34=P3^4;//测温DQ sbit P35=P3^5;//发声端口 char dplib[11]={0x018,0x07B,0x02C,0x029,0x04B,0x089,0x088,0x03B,0x08,0x09,0x0EF};//数 码管 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf char dpbuf[4];//每个数码管显示的数字缓冲区 int t=0;//控制循环次数或标志位 int s0=0;//用于延时或循环或标志位 int s1=0;//用于延时或循环或标志位 unsigned char acc=0;//用于对温度芯片的读写操作 int high_time,low_time,count=0;//占空比调节参数 float temper; int TTL=1,huansuan,TH1Z1,TL1Z1,TH1Z0,TL1Z0;//用于脉宽调制 int sign=0;//sign为1,则小数点显示,否则小数点不显示 int dnt=0;//用于位选挨个点亮 int cnt=0;//用于控制是否一直按着加键或者减键 int shujua;//读出温度数据的高位 int shujub;//温度低位 int zancun=0;//临时数据存放 int watchdog=0;//软件看门狗,无操作定时返回退出 /*********************************************************** PID类 ***********************************************************/ struct PID { int SetPoint; // 设定目标 Desired Value int Proportion; // 比例常数 Proportional Const int Integral; // 积分常数 Integral Const int Derivative; // 微分常数 Derivative Const float LastError; // Error[-1] float PrevError; // Error[-2] float SumError; // Sums of Errors }; struct PID spid; // PID Control Structure float rout; // PID Response (Output) float rin; // PID Feedback (Input) void keyprogram();//键盘参数设置子程序 void observe();//运行中观察设置参数子程序 void settingmode();//选择要设定的参数子程序 void addmode();//参数加 void submode();//参数减 void displaysetting(int mode);//键盘操作时显示的设置 void INIT18B20();//初始芯片 void WRBYTE(unsigned char a);//写字 void RDBYTE( );//读字 void delay10ms(void);//10MS延时,用于显示2S void get_temper();//温度测量子程序 void change(int a,int b);//对读出数据处理,与汇编原理一样 /*********************************************************** T0中断服务程序 ***********************************************************/ void timer0(void)interrupt 1 using 2//T0中断 { TH0=0xEE; TL0=0x00; dp2=dp4=dp3=dp1=1; if(dnt>3) {dnt=0;} if((dnt==1)&&(sign==1)) P0=dplib[dpbuf[dnt]]&0XF7; else { P0=dplib[dpbuf[dnt]]; watchdog++; } switch(dnt++) { case 0: dp1=0; break; case 1: dp2=0; break; case 2: dp3=0; break; case 3: dp4=0; } } /*********************************************************** T1中断服务程序 ***********************************************************/ void serve_T1() interrupt 3 using 3 //T1 { if(TTL==1) { P13=1; TH1=TH1Z1; TL1=TL1Z1; TTL=0; } else { P13=0; TH1=TH1Z0; TL1=TL1Z0; TTL=1; } if(count==9) count=0; else count++; } /*==================================================================== ================================ 初始化PID类 ====================================================================== ===============================*/ void PIDInit (struct PID *pp) { memset ( pp,0,sizeof(struct PID)); } /*==================================================================== ================================ PID计算部分 ====================================================================== ===============================*/ float PIDCalc( struct PID *pp, float NextPoint ) { float dError,Error; Error = pp->SetPoint - NextPoint; // 偏差 pp->SumError += Error; // 积分 dError = pp->LastError - pp->PrevError; // 当前微分 pp->PrevError = pp->LastError; pp->LastError = Error; if(abs(spid.SetPoint-temper)<0.5) pp->SumError=0; return (pp->Proportion * Error//比例 + pp->Integral * pp->SumError //积分项 + pp->Derivative * dError); // 微分项 } /*********************************************************** 温度控制子程序 ***********************************************************/ void control_temper() { if(spid.SetPoint-temper>4) { high_time=high_time+100;//高电平份数累加 } else if(temper-spid.SetPoint>4) { high_time=high_time-110;//高电平份数累减 } else if(abs(temper-spid.SetPoint)<4) { rin=temper; rout = PIDCalc( &spid,rin ); // 进入PID计算 high_time=high_time+rout; } if(high_time>=1000)//防止过热过冷 high_time=999; if(high_time<0) high_time=1; low_time=1000-high_time; //得到低电平份数 huansuan=65536-high_time*46;//换算得到T1定时器初值 TH1Z1=(huansuan&0xFF00>>8); TL1Z1=huansuan&0x00FF; huansuan=65536-low_time*46; TH1Z0=(huansuan&0xFF00>>8); TL1Z0=huansuan&0x00FF; } /*********************************************************** 温度测量子程序 ***********************************************************/ void get_temper() { EA=0; INIT18B20(); acc=0xCC; WRBYTE(acc); acc=0x44; WRBYTE(acc); INIT18B20(); acc=0xCC; WRBYTE(acc); acc=0xBE; WRBYTE(acc); RDBYTE(); shujub=(int)acc; RDBYTE(); shujua=(int)acc; change(shujua,shujub); EA=1; } /*********************************************************** 初始化DS18B20 ***********************************************************/ void INIT18B20() { t=4; P34=0; s0=62; for(s0;s0>0;s0--);//延时500us P34=1; CY=0; s0=6; while(t--) { while(s0--) { if(P34==1) { t=0; s1=1; break; } } } if(s1==1) { s0=111; while(s0--) { CY=CY|P34; } } } /*********************************************************** 向DS18B20写字 ***********************************************************/ void WRBYTE(unsigned char a) { t=8; CY=0; while(t--) { a=(a>>1); P34=0; _nop_() ; _nop_() ; _nop_() ; _nop_() ; _nop_() ; P34=CY; s0=3; for(s0;s0>0;s0--); P34=1; } } /*********************************************************** 向DS18B20读字 ***********************************************************/ void RDBYTE( ) {acc=0; t=8; while(t--) { P34=0; _nop_() ; _nop_() ; _nop_(); _nop_(); _nop_() ; _nop_() ; _nop_() ; _nop_() ; _nop_() ; _nop_() ; _nop_() ; _nop_() ; _nop_() ; _nop_() ; _nop_() ; P34=1; CY=P34; _nop_() ; _nop_() ; _nop_() ; _nop_() ; s0=5; for(s0;s0>0;s0--); P34=1; if(CY==1) { acc=acc|0x80; if(t) { acc=(acc>>1); } } else if(t) { acc=(acc>>1); } } } /*********************************************************** 处理从DS18B20上读到的数值子程序 ***********************************************************/ void change(a,b) { int zheng; int xiaoshu; zheng=((shujua&(0x07))<<4)+((shujub&(0xF0))>>4);//处理整数,转换BCD temper=zheng; xiaoshu=shujub&0x0F;//处理小数,转换BCD zancun=((xiaoshu*10)&0xF0); temper=temper+(float)(zancun>>4)/10; if(sign==1) { dpbuf[3]=zheng/100; zheng=zheng%100; dpbuf[2]=zheng/10; zheng=zheng%10; dpbuf[1]=zheng; dpbuf[0]=(zancun>>4); } } /*********************************************************** 延时子程序 ***********************************************************/ void delay10ms(void)//10ms { unsigned char i0,j0; for(i0=20;i0>0;i0--) for(j0=248;j0>0;j0--); } /*********************************************************** 参数设定子程序 ***********************************************************/ void keyprogram() { if(key1==0)//判断是否进入设置 { //A delay10ms(); if(key1==0)//进入设置了 { P13=0; while(!key1); sign=0; //B dpbuf[2]=spid.SetPoint/100; zancun=(int)spid.SetPoint%100; dpbuf[1]=zancun/10; zancun=zancun%10; dpbuf[0]=zancun; dpbuf[3]=1;//从模式一开始选择 while(1) { if(key2==0)//判断是否进行参数选择 { settingmode();//参数选择子程序 } if(key3==0)//判断是否进行参数加 { addmode();//参数加子程序 } if(key4==0)//判断是否进行参数减减 { submode();//参数减子程序 } if(key1==0)//判断是否进行参数加加 { delay10ms(); if(key1==0) { while(!key1); break; } } if((key3==1)&&(key4==1))// { delay10ms(); if((key3==1)&&(key4==1)) cnt=0; } if(watchdog==2000) { watchdog=0; break; } } } //B }//A watchdog=0; sign=1; } /*********************************************************** 观察参数子程序 ***********************************************************/ void observe() { if(key4==0)//判断是否进入设置 { //A delay10ms(); if(key4==0)//进入设置了 { while(!key4); sign=0; //B dpbuf[2]=spid.SetPoint/100; zancun=(int)spid.SetPoint%100; dpbuf[1]=zancun/10; zancun=zancun%10; dpbuf[0]=zancun; dpbuf[3]=1;//从模式一开始观察 while(1) { if(key2==0)//判断是否进行参数选择 { settingmode();//参数选择子程序 } if(key4==0)//判断是否结束观察 { delay10ms(); if(key4==0) { while(!key4); break; } } if(watchdog==2000) { watchdog=0; break; } if(count==10) { get_temper();//温度测量子程序 control_temper();//温度控制子程序 } } } //B }//A sign=1; watchdog=0; } /*********************************************************** 设置模式子程序 ***********************************************************/ void settingmode() { delay10ms(); if(key2==0)//进入了模式选择 { while(!key2); if(++dpbuf[3]==5) { dpbuf[3]=1; } displaysetting(1); dpbuf[2]=zancun/100; zancun=zancun%100; dpbuf[1]=zancun/10; zancun=zancun%10; dpbuf[0]=zancun; } } /*********************************************************** 参数加子程序 ***********************************************************/ void addmode() { delay10ms(); displaysetting(1); if(key3==0) { if(cnt==0) { t=70; while((--t)&&(!key3)) { delay10ms();} if(t==0) cnt++; zancun++; } else if(cnt<10) { cnt++; t=30; while(t--) { delay10ms();} zancun++; } else if(cnt==19) {cnt=19; t=30; while(t--) { delay10ms();} zancun+=100; } else if(cnt>=10) { cnt++; t=30; while(t--) { delay10ms();} zancun+=10; } } if(dpbuf[3]==1) { if(zancun>100) zancun=30; } else if(zancun>800) zancun=0; displaysetting(2); } /*********************************************************** 参数减子程序 ***********************************************************/ void submode() { delay10ms(); displaysetting(1); if(key4==0) { if(cnt==0) { t=75; while((--t)&&(!key4)) { delay10ms();} if(t==0) cnt++; zancun--; } else if(cnt<10) { cnt++; t=30; while(t--) { delay10ms();} zancun--; } else if(cnt==19) {cnt=19; t=30; while(t--) { delay10ms();} zancun-=100; } else if(cnt>=10) { cnt++; t=30; while(t--) { delay10ms();} zancun-=10; } } if(dpbuf[3]==1) { if(zancun<30) zancun=100; } else if(zancun<0) zancun=800; displaysetting(2); } /*********************************************************** 按键时显示设置子程序 ***********************************************************/ void displaysetting(int mode) { if(mode==1) { switch(dpbuf[3]) { case 1:zancun=spid.SetPoint;break; case 2:zancun=spid.Proportion;break; case 3:zancun=spid.Integral;break; case 4:zancun=spid.Derivative; } } else { switch(dpbuf[3]) { case 1:spid.SetPoint=zancun;break; case 2:spid.Proportion=zancun;break; case 3:spid.Integral=zancun;break; case 4:spid.Derivative=zancun; } dpbuf[2]=zancun/100; zancun=zancun%100; dpbuf[1]=zancun/10; zancun=zancun%10; dpbuf[0]=zancun; } watchdog=0; } /*********************************************************** 主程序 ***********************************************************/ void main() { dpbuf[0]=0; dpbuf[1]=0; dpbuf[2]=0; dpbuf[3]=0; TMOD=0X11; TH0=0XEE; TL0=0X00; TH1=0x00; TL1=0x00; ET0=1; ET1=1; PT1=1; PT0=0; EA=1; TR0=1; TR1=1; high_time=500; low_time=500; PIDInit ( &spid ); spid.SetPoint=30; //初始化各个参数,定时器等 while(1) { keyprogram(); observe(); if(count==9) { get_temper(); control_temper(); } } }
本文档为【温度pid控制】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_321575
暂无简介~
格式:doc
大小:49KB
软件:Word
页数:26
分类:管理学
上传时间:2017-10-12
浏览量:28