找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2493|回复: 0
收起左侧

增量式pid控制 单片机源程序

[复制链接]
ID:811720 发表于 2020-8-6 00:03 | 显示全部楼层 |阅读模式
单片机源程序如下:
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #include <absacc.h>
  4. #include "define.h"
  5. #include "delay.h"
  6. #include "da0832.h"
  7. #include "DS18B20_5.h"
  8. #include "lcd1602.h"
  9. #include "zlg.h"
  10. #define PMAX 100
  11. #define PMIN 0
  12. typedef struct
  13. {
  14.         char kp,ki,kd;
  15.         int e2,e1,e0;
  16.         long  pa,vpa;
  17. }mypid;
  18. mypid p1;
  19. int final_tem,cur_tem;
  20. //uchar point_on;

  21. //sbit point0=P1^3;
  22. //sbit pout=P1^4;
  23. #define Time_Unit 80
  24. uchar num_unit=0;
  25. uint num100unit=0;
  26. int2char pwm_dtime;
  27. uchar Action();//执行控制量
  28. uint Set_Tem4();//设定4位的温度值
  29. int PID();//增量式pid算法,输出为控制量增量p1.vpa 和 p1.pa
  30. void main()
  31. {
  32.         uchar keyv;
  33.         Lcd_Initial();
  34.         Key_Initial();
  35.         p1.kp=50;//pid参数设置
  36.         p1.ki=10;
  37.         p1.kd=5;

  38.         da_1=0;
  39.         final_tem=Set_Tem4();//设定温度
  40.         p1.pa=0;
  41.         p1.e2=0;
  42.         p1.e1=0;
  43.         p1.e0=0;
  44.         //point_on=100;//不导通

  45.         TR0=0;//开定时器0       
  46.         TMOD=0x11;
  47.         TH0=0xff;
  48.         TL0=0xe0;
  49.         TR0=1;
  50.         IE=IE|0x02;
  51.         EA=1;
  52.         num_unit=0;

  53.         //=======================以上为始化
  54.         while(1)
  55.         {
  56.                 if(key)//查询按键
  57.                 {
  58.                         keyv=Keyscan();
  59.                         if(keyv==15)
  60.                         {       
  61.                                 da_1=0;
  62.                                 final_tem=Set_Tem4();//设定温度
  63.                                 p1.pa=0;
  64.                                 p1.e2=0;
  65.                                 p1.e1=0;
  66.                                 p1.e0=0;
  67.                                 //point_on=100;//不导通
  68.                         }
  69.                         else if(keyv==14)//停止加热
  70.                         {
  71.                                 EA=0;
  72.                                 //pout=0;
  73.                                 da_1=0;
  74.                         }
  75.                 }
  76.                 if((num100unit&0x00ff)==0)//2.56s为周期
  77.                 {
  78.                         Lcd_Puts(1,0,"aim_tem:");
  79.                         Lcd_Putfloat(9,0,3,1,final_tem);
  80.                         cur_tem=GetTemperature();//读取当前温度值并显示
  81.                         Lcd_Puts(1,1,"now_tem:");
  82.                         Lcd_Putfloat(9,1,3,1,cur_tem);
  83.                         PID();//pid控制
  84.                         Action();//控制执行
  85.                 }
  86.         }
  87. }
  88. uint Set_Tem4()//设定4位的温度值
  89. {
  90.         uchar a,b,c,d;
  91.         Lcd_Clr();
  92.         Lcd_Puts(1,0,"set Tem:");
  93.         while(!key);
  94.         a=Keyscan();
  95.         Lcd_Putint(10,0,1,a);
  96.         while(!key);
  97.         b=Keyscan();
  98.         Lcd_Putint(11,0,1,b);
  99.         while(!key);
  100.         c=Keyscan();
  101.         Lcd_Putint(12,0,1,c);
  102.         while(!key);
  103.         d=Keyscan();
  104.         Lcd_Putint(13,0,1,d);
  105.         return (a*1000+b*100+c*10+d);       
  106. }

  107. void Int_T0()interrupt 1 using 2 //ie0x02//TMOD=0x11;
  108. {
  109.         EA=0;
  110.         TR0=0;       
  111.         pwm_dtime.time=0xffff-Time_Unit;
  112.         TH0=pwm_dtime.hl[0];
  113.         TL0=pwm_dtime.hl[1];//定时us
  114.         TR0=1;//开定时器0
  115.         //t0f=1;//标志置1
  116.         /*if(point0==0)//查询到0点
  117.         {
  118.                 num_unit=0;
  119.         }*/
  120.         if(num_unit==100)
  121.         {
  122.                 num_unit=0;
  123.                 num100unit++;
  124.         }
  125.         /*if(num_unit==0)//0点不导通
  126.         {
  127.                 pout=0;
  128.         }
  129.         if(num_unit==point_on)//导通点
  130.         {
  131.                 pout=1;
  132.         }*/
  133.         num_unit++;
  134.         EA=1;
  135. }
  136. int PID()//增量式pid算法,输出为控制量增量p1.vpa 和 p1.pa
  137. {
  138.         p1.e2=final_tem - cur_tem;
  139.         p1.vpa=p1.kp*((long)p1.e2-p1.e1)
  140.                         +p1.ki*(long)p1.e2
  141.                         +p1.kd*((long)p1.e2+p1.e0-2*p1.e1);
  142.         p1.e1=p1.e2;
  143.         p1.e0=p1.e1;
  144.         p1.pa+=p1.vpa;
  145. }
  146. uchar Action()//执行控制量
  147. {
  148.         long temp;
  149.         if(p1.pa>0)//控制量大于0
  150.         {
  151.                 temp=p1.pa;
  152.                 temp=temp>>5;
  153.                 if(temp>PMAX)//完全导通
  154.                 {
  155.                         //point_on=0;
  156.                         da_1=255;
  157.                 }
  158.                 else if(temp<PMIN)//完全截至
  159.                 {
  160.                         //point_on=100;
  161.                         da_1=0;
  162.                 }
  163.                 else
  164.                 {
  165.                         //point_on=100*(PMAX-temp)/(PMAX-PMIN);
  166.                         da_1=255*temp/(PMAX-PMIN);
  167.                 }
  168.         }
  169.         else
  170.         {
  171.                 //point_on=100;//完全截至
  172.                 da_1=0;
  173.         }
  174.         return 1;
  175. }
复制代码
51hei.png
所有资料51hei提供下载:
增量式pid-da控制.rar (56.58 KB, 下载次数: 50)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表