单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- #include <absacc.h>
- #include "define.h"
- #include "delay.h"
- #include "da0832.h"
- #include "DS18B20_5.h"
- #include "lcd1602.h"
- #include "zlg.h"
- #define PMAX 100
- #define PMIN 0
- typedef struct
- {
- char kp,ki,kd;
- int e2,e1,e0;
- long pa,vpa;
- }mypid;
- mypid p1;
- int final_tem,cur_tem;
- //uchar point_on;
- //sbit point0=P1^3;
- //sbit pout=P1^4;
- #define Time_Unit 80
- uchar num_unit=0;
- uint num100unit=0;
- int2char pwm_dtime;
- uchar Action();//执行控制量
- uint Set_Tem4();//设定4位的温度值
- int PID();//增量式pid算法,输出为控制量增量p1.vpa 和 p1.pa
- void main()
- {
- uchar keyv;
- Lcd_Initial();
- Key_Initial();
- p1.kp=50;//pid参数设置
- p1.ki=10;
- p1.kd=5;
- da_1=0;
- final_tem=Set_Tem4();//设定温度
- p1.pa=0;
- p1.e2=0;
- p1.e1=0;
- p1.e0=0;
- //point_on=100;//不导通
- TR0=0;//开定时器0
- TMOD=0x11;
- TH0=0xff;
- TL0=0xe0;
- TR0=1;
- IE=IE|0x02;
- EA=1;
- num_unit=0;
- //=======================以上为始化
- while(1)
- {
- if(key)//查询按键
- {
- keyv=Keyscan();
- if(keyv==15)
- {
- da_1=0;
- final_tem=Set_Tem4();//设定温度
- p1.pa=0;
- p1.e2=0;
- p1.e1=0;
- p1.e0=0;
- //point_on=100;//不导通
- }
- else if(keyv==14)//停止加热
- {
- EA=0;
- //pout=0;
- da_1=0;
- }
- }
- if((num100unit&0x00ff)==0)//2.56s为周期
- {
- Lcd_Puts(1,0,"aim_tem:");
- Lcd_Putfloat(9,0,3,1,final_tem);
- cur_tem=GetTemperature();//读取当前温度值并显示
- Lcd_Puts(1,1,"now_tem:");
- Lcd_Putfloat(9,1,3,1,cur_tem);
- PID();//pid控制
- Action();//控制执行
- }
- }
- }
- uint Set_Tem4()//设定4位的温度值
- {
- uchar a,b,c,d;
- Lcd_Clr();
- Lcd_Puts(1,0,"set Tem:");
- while(!key);
- a=Keyscan();
- Lcd_Putint(10,0,1,a);
- while(!key);
- b=Keyscan();
- Lcd_Putint(11,0,1,b);
- while(!key);
- c=Keyscan();
- Lcd_Putint(12,0,1,c);
- while(!key);
- d=Keyscan();
- Lcd_Putint(13,0,1,d);
- return (a*1000+b*100+c*10+d);
- }
- void Int_T0()interrupt 1 using 2 //ie0x02//TMOD=0x11;
- {
- EA=0;
- TR0=0;
- pwm_dtime.time=0xffff-Time_Unit;
- TH0=pwm_dtime.hl[0];
- TL0=pwm_dtime.hl[1];//定时us
- TR0=1;//开定时器0
- //t0f=1;//标志置1
- /*if(point0==0)//查询到0点
- {
- num_unit=0;
- }*/
- if(num_unit==100)
- {
- num_unit=0;
- num100unit++;
- }
- /*if(num_unit==0)//0点不导通
- {
- pout=0;
- }
- if(num_unit==point_on)//导通点
- {
- pout=1;
- }*/
- num_unit++;
- EA=1;
- }
- int PID()//增量式pid算法,输出为控制量增量p1.vpa 和 p1.pa
- {
- p1.e2=final_tem - cur_tem;
- p1.vpa=p1.kp*((long)p1.e2-p1.e1)
- +p1.ki*(long)p1.e2
- +p1.kd*((long)p1.e2+p1.e0-2*p1.e1);
- p1.e1=p1.e2;
- p1.e0=p1.e1;
- p1.pa+=p1.vpa;
- }
- uchar Action()//执行控制量
- {
- long temp;
- if(p1.pa>0)//控制量大于0
- {
- temp=p1.pa;
- temp=temp>>5;
- if(temp>PMAX)//完全导通
- {
- //point_on=0;
- da_1=255;
- }
- else if(temp<PMIN)//完全截至
- {
- //point_on=100;
- da_1=0;
- }
- else
- {
- //point_on=100*(PMAX-temp)/(PMAX-PMIN);
- da_1=255*temp/(PMAX-PMIN);
- }
- }
- else
- {
- //point_on=100;//完全截至
- da_1=0;
- }
- return 1;
- }
复制代码
所有资料51hei提供下载:
增量式pid-da控制.rar
(56.58 KB, 下载次数: 50)
|