找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5144|回复: 6
收起左侧

STM32模糊控制pid 控制烤箱温度 含源码

  [复制链接]
ID:806057 发表于 2020-7-20 22:36 | 显示全部楼层 |阅读模式
控制系统用stm32当主控
Ds18b20当温度传感器
通过电调控制加热棒
模糊控制算法+pid控制温度

单片机源程序如下:
  1. #include "pid.h"

  2. void PIDInit (struct PID *pp)
  3. {
  4. memset ( pp,0,sizeof(struct PID));
  5. }

  6. float PIDCalc( struct PID *pp, float temp2  )
  7. {
  8.         
  9.     float Error,Error1,Error2,a;

  10.     Error=pp->Setval-temp2; ///e(k)

  11.     Error1 = Error - pp->LastError;//e(k)-e(k-1)
  12.     Error2 =Error - pp->LastError - pp->LastError + pp->PrevError;//e(k)-2*e(k-1)+e(k-2)
  13.     pp->PrevError = pp->LastError; //e(k-2)=e(k-1)
  14.     pp->LastError = Error;//e(k-1)=e(k)
  15.    //rout1=a;
  16.    a=pp->Proportion * Error1+ pp->Integral * Error + pp->Derivative * Error2;



  17.         return a*1000;
复制代码

代码敲的倒是挺快 参数调了好长时间。。。。

  1. #include "stm32f10x.h"
  2. #include "led.h"
  3. #include "Delay.h"
  4. #include "key.h"
  5. #include "usart.h"
  6. #include "adc.h"
  7. #include "lcd.h"
  8. #include "flash.h"
  9. #include "ds18b20.h"
  10. #include "stm32f10x_gpio.h"
  11. #include "stm32f10x_dac.h"
  12. #include "pid.h"
  13. #include "dac.h"        
  14. #include "spi.h"
  15. #include "stdio.h"

  16. #define kp 33        //33
  17. #define ki 0.12       //0.12
  18. #define kd 6.5

  19. #define SCLK PBout(13)   
  20. #define CS PBout(11)           
  21. #define DIN PBout(15)



  22. char tempdata[4]={0,0,'.',0};
  23. float set_temper=40;
  24. float temp;
  25. float temp1;
  26. float temp2;
  27. float out;
  28. float DA_Value;
  29. struct PID spid ; // PID Control Structure
  30. char pid[3];
  31. float e1,e2;
  32. float temp_kpi=0;
  33. float rout;
  34. float rout1;
  35. float rout2;
  36. float rout3;
  37. float out1;
  38. float out2;
  39. float tranDA=0;

  40.   void fuzzypid(float ew,float ec,char *pid)
  41. {
  42.           char ee,ecec,i,j;
  43.                  char eec[][7]=
  44.         {
  45.                 -3,-2,-1,0,1,2,3,
  46.                 -3,-2,-1,0,1,2,3
  47.                
  48.         };
  49.            char KpRule[7][7]=                                //KpμÄÄ£oy¿ØÖƱí
  50.                 {3,3,3,2,1,0,0,
  51.                 3,3,2,2,1,0,-1,
  52.                 3,3,2,1,0,-1,-1,
  53.                 2,2,1,0,0,-1,-2,
  54.                 1,1,0,-1,-1,-2,-2,
  55.                 1,1,-1,-2,-2,-3,-3,
  56.          -1,-1,-2,-2,-3,-3,-3};
  57.         
  58.            char KiRule[7][7]=                                //KpμÄÄ£oy¿ØÖƱí
  59.                 {-3,-3,-2,-2,-1,-1,0,
  60.                 -3,-3,-2,-1,-1,0,0,
  61.                 -3,-2,-1,-1,0,1,2,
  62.                 -2,-1,-1,0,0,1,2,
  63.                 -2,-1,0,1,2,2,3,
  64.                 0,0,0,1,2,2,3,
  65.                 0,0,1,2,3,3,3,};
  66.         
  67.            char KdRule[7][7]=                                //KpμÄÄ£oy¿ØÖƱí
  68.                 {1,-1,-3,-3,-2,-2,1,
  69.                 1,-1,-3,-2,-2,-1,0,
  70.                 0,-1,-2,-2,-1,0,0,
  71.                 0,0,-1,-1,-1,0,-1,
  72.                 -1,-1,-1,0,0,0,0,
  73.                 3,1,1,1,1,2,3,
  74.                 3,3,2,2,1,1,3};
  75.          
  76.           if(ew>=0)ee=ew*0.6+0.5;
  77.           else ee=-(fabs(ew*0.6)+0.5);//???
  78.         
  79.           if(ec>=0)ecec=ec*10+0.5;
  80.           else ecec=-(fabs(ec*10)+0.5);
  81.         

  82.            for(j=0;j<7;j++)
  83.         {
  84.                 if(eec[0][j]==ee)break;        
  85.                         
  86.         }
  87.           for(i=0;i<7;i++)
  88.            {
  89.                 if(eec[1][i]==ecec)break;                        
  90.                 }
  91.         pid[0]=KpRule[i][j];
  92.         pid[1]=KiRule[i][j];
  93.         pid[2]=KdRule[i][j];
  94.                
  95. }



  96.         void compare_temper()
  97.      {
  98.                   float temp_kpi=0;
  99.                                                 rout = PIDCalc ( &spid,temp1 );
  100.                                     rout2 = rout + rout1;
  101.                               rout1=rout;
  102.                                                 
  103.                                                 if (e1<-5) e1=-5;
  104.                                                 else if(e1<=5);                                                        
  105.                                                 else e1=5;
  106.                                                 if (e2<-0.3) e2=-0.3;
  107.                                                 else if(e2<=0.3);                                                        
  108.                                                 else e2=0.3;
  109.                         
  110.                                         fuzzypid(e1,e2,pid);
  111.                                                 
  112.                                         temp_kpi=pid[0];
  113.                                         spid.Proportion=kp+temp_kpi*1;
  114.                                         temp_kpi=pid[1];
  115.                                         spid.Integral =ki+temp_kpi*0.01;
  116.                                         temp_kpi=pid[2];
  117.                                         spid.Derivative =kd+temp_kpi*0.1;                 


  118. }



  119.     int main(void)
  120.    {               
  121.            u8 t=0;        

  122.           short temperature;  
  123.         
  124.           LED_Init();//LED3õê¼»ˉ
  125.     KEY_Init();//°′¼ü3õê¼»ˉ
  126.     SysTick_Init();//Ñóê±3õê¼»ˉ
  127.     USART1_Int(9600);
  128.           Dac1_Init();
  129.           SPI2_Init();
  130.           PIDInit ( &spid ); // Initialize Structure
  131.          spid.Proportion = kp; // Set PID Coefficients
  132.    spid.Integral = ki;
  133.    spid.Derivative =kd;         
  134.          spid.Setval = set_temper;

  135.         LCD_Init();
  136.   printf(" LCD DS18B20 ζèÏÔê¾r");                  
  137.          POINT_COLOR=GREEN;
  138.         LCD_ShowString(40,20,200,16,16,"STM32");        
  139.         LCD_ShowString(40,40,200,16,16,"DS18B20 ");        
  140.         LCD_ShowString(40,60,200,20,16,"mengfangang biyesheji");
  141.         LCD_ShowString(40,80,200,16,16,"zhidaolaoshi gaohongyan");        

  142.         
  143.          while(DS18B20_Init())        //DS18B203õê¼»ˉ        
  144.         {  POINT_COLOR=RED;
  145.                  LCD_ShowString(40,100,200,16,16,"DS18B20 Error");
  146.                  Delay_ms(200);
  147.                  LCD_Fill(60,130,239,130+16,BROWN);
  148.                   Delay_ms(200);
  149.         }        
  150.            POINT_COLOR=RED;                                                   
  151.            LCD_ShowString(40,120,200,16,16,"DS18B20 OK");
  152.            POINT_COLOR=BLUE;//éèÖÃ×ÖìåÎaà¶é«
  153.             LCD_ShowString(40,160,200,16,16,"Temperate:    .  C");                 
  154.      LCD_ShowString(40,140,200,16,16,"set_temper:      C");               
  155.    
  156.           LCD_ShowString(40,240,200,16,16,"rout:    ");
  157.           LCD_ShowString(40,260,200,16,16,"rout1:    ");
  158.         LCD_ShowString(40,280,200,16,16,"out:    ");
  159.         while(1)
  160.         {
  161.         if(t%10==0)//ÿ100ms¶áè¡ò»′Î
  162.                 {                                                                          
  163.                          temperature=DS18B20_Get_Temp();
  164.                          temp1=temperature/10.0;
  165.    
  166.                         
  167.                     printf("%8.5f",temp1);

  168.                      compare_temper() ;
  169.                            out=rout2;
  170.                                  if(out>=2000)
  171.                                {out1=2200;}
  172.                                 // else
  173.                                         // out1=rout;
  174. //                                 {if(1600<out&&out<2400)
  175. //             {out1=out*1.2;}
  176. //           else
  177. //                                         {if(1000<out&&out<1600)
  178. //              {out1=out*1.4;}
  179. //            else
  180. //                                                {if(800<out&&out<1000)
  181. //                                                {out1=out*1.8;}
  182. //                                                else
  183. //                                                {        if(600<out&&out<800)
  184. //                                                   {out1=out*1.5;}  
  185. //            else
  186. //                                                {                if(400<out&&out<600)
  187. //                                                         {out1=out*3.5;}
  188. //                                                else
  189. //                                                {if(200<out&&out<400)
  190. //                                                        {out1=out*7;}
  191. //                                                        else
  192. //                                                        {if(150<out&&out<200)        
  193. //                                                        {out1=out*7;}
  194. //                                                        else
  195. //                                                        {        if(100<out&&out<150)
  196. //                                                                {out1=out*10;}
  197.                                                                 else
  198.                                                                         
  199.                                                                
  200.                                                                
  201.                                                                
  202.                                                                
  203.                                                                
  204.                                                                
  205.                                                                
  206. //                                                                {if(100<out&&out<230)
  207. //                                                                        {out1=out*1.5;}
  208. //                                                                        else
  209. //                                                                                
  210.                                                                         
  211.                                                                         
  212.                                                                         
  213.                                                                         
  214.                                                                         
  215.                                                                 {        if(0<out&&out<150)
  216.                                                         {rout3=700;out1=out*10+rout3;}
  217.                                                  }
  218. //                                                        else
  219. //                                                        {if(0>out)
  220. //                                                        {out2=1800;}
  221. //                                                        else
  222. //                                                                out1=0;
  223. //                                                        }
  224. //                                                        }        
  225. //                                                }
  226. //                                 }
  227. //                         }
  228. //                 }
  229. //         }                        
  230. //         }
  231. // }                                
  232. // }
  233. //                                 if(2500>rout&&rout>=1200)
  234. //                                 {out=2000;}
  235. //                                 else
  236. //                                 if(1200>rout&&rout>=900)
  237. //                                 { out=rout*2; }
  238. //        
  239. //                                 else
  240. //                                 if(900>rout&&rout>=0)
  241. //                                 { out=1950; }
  242. //                                 else
  243. //                                 out=1950;
  244.                                  
  245.                                  
  246.                                  
  247.                                  
  248.                                  
  249.                                  
  250.                                  
  251. //                             if(rout>=250)
  252. //                                   {out=1800;}               
  253. //                                        else
  254. //                                        {                                                
  255. //                                                        if(250>rout&&rout>=120)
  256. //                                                                {out=2600; }        
  257. //                                                        else
  258. //                                                        {if(120>rout&&rout>=70)        
  259. //                                                                {out=2200; }
  260. //                                                        else               
  261. //                                                        {        
  262. //                                                                if(70>rout&&rout>=50)
  263. //                                                                        {out=rout*30; }
  264. //                                                                else
  265. //                                                                {               
  266. //                                                                        if(50>rout&&rout>=45)
  267. //                                                                                        {out=rout*30; }
  268. //                                                                        else
  269. //                                                                        {
  270. //                                                                                if(45>rout&&rout>=35)
  271. //                                                                                                { out=rout*30;}
  272. //                                                                                else
  273. //                                                                                {        if(35>rout&&rout>=30)
  274. //                                                                                                {out=rout*45;}
  275. //                                                                                        else        
  276. //                                                                                        {if(29>rout&&rout>=25)
  277. //                                                                                                {out=rout*60;}
  278. //                                                                                                else
  279. //                                                                                                {if(25>rout&&rout>=15)
  280. //                                                                                                {out=rout*30;}
  281. //                                                                                                else
  282. //                                                                                                
  283. //                                                                                        {if(15>rout&&rout>=0)
  284. //                                                                                                {out=2400;}
  285. //                                                                                                else
  286. //                                                                                                {if(0>rout&&rout>=-15)
  287. //                                                                                             {out=2300;}
  288. //                                                
  289. //                                                                                                }
  290. //                                                                                        }        
  291. //                        
  292. //                                                                                        }                                                                        
  293. //                                                                                       
  294. //                                                                                        }        
  295. //                                                
  296. //                                                                                }
  297. //                                                                        }
  298. //                                                                }
  299. //                                                        }
  300. //                                 }
  301. //                         }
  302.      if(temp1>41)
  303.                  {Dac1_Set_Vol(0);}
  304.                  else
  305.                  {Dac1_Set_Vol(out1);}

  306.                                          
  307.                                          
  308.                          if(temperature<0)
  309.                         {
  310.                                 LCD_ShowChar(60+80,150,'-',16,0);     
  311.                                 temperature=-temperature;   
  312.                         }
  313.                         LCD_ShowChar(60+80,150,' ',16,0);     
  314.             LCD_ShowNum(120+14,160,temperature/10,2,16);   
  315.       LCD_ShowNum(140+16,160,temperature%10,2,16);                     
  316.                   LCD_ShowNum(134,140,set_temper,2,16);
  317.                
  318.                         LCD_ShowNum(140+16,240,rout,5,16);
  319.       LCD_ShowNum(140+16,260,rout1,5,16);                        
  320.       LCD_ShowNum(140+16,280,out,5,16);
  321.                 }        
  322.                  Delay_ms(10);
  323.                 t++;
  324.                 if(t==20)
  325.                 {
  326.                         t=0;
  327.                         LED2_REV;
  328.                 }
  329.         }

  330. }
复制代码

回复

使用道具 举报

ID:276663 发表于 2020-7-21 10:13 | 显示全部楼层
有测个温度曲线吗?可以直观的看出来参数调整的效果如何
回复

使用道具 举报

ID:807794 发表于 2020-7-25 01:35 | 显示全部楼层
有rule波型可以參考嗎?
回复

使用道具 举报

ID:576070 发表于 2020-7-29 13:54 | 显示全部楼层
请问楼主批量测试过吗?
回复

使用道具 举报

ID:279380 发表于 2020-8-15 22:09 | 显示全部楼层
思路好,下下来测试下,谢谢楼主!
回复

使用道具 举报

ID:406128 发表于 2021-9-1 17:23 | 显示全部楼层
源码可否给打包一个
回复

使用道具 举报

ID:710888 发表于 2021-9-2 10:34 | 显示全部楼层
呵呵,最好有配套的电路描述,采样部分做的不好误差比较大
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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