标题:
STM32模糊控制pid 控制烤箱温度 含源码
[打印本页]
作者:
tx-nick
时间:
2020-7-20 22:36
标题:
STM32模糊控制pid 控制烤箱温度 含源码
控制系统用stm32当主控
Ds18b20当温度传感器
通过电调控制加热棒
模糊控制算法+pid控制温度
单片机源程序如下:
#include "pid.h"
void PIDInit (struct PID *pp)
{
memset ( pp,0,sizeof(struct PID));
}
float PIDCalc( struct PID *pp, float temp2 )
{
float Error,Error1,Error2,a;
Error=pp->Setval-temp2; ///e(k)
Error1 = Error - pp->LastError;//e(k)-e(k-1)
Error2 =Error - pp->LastError - pp->LastError + pp->PrevError;//e(k)-2*e(k-1)+e(k-2)
pp->PrevError = pp->LastError; //e(k-2)=e(k-1)
pp->LastError = Error;//e(k-1)=e(k)
//rout1=a;
a=pp->Proportion * Error1+ pp->Integral * Error + pp->Derivative * Error2;
return a*1000;
复制代码
代码敲的倒是挺快 参数调了好长时间。。。。
#include "stm32f10x.h"
#include "led.h"
#include "Delay.h"
#include "key.h"
#include "usart.h"
#include "adc.h"
#include "lcd.h"
#include "flash.h"
#include "ds18b20.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_dac.h"
#include "pid.h"
#include "dac.h"
#include "spi.h"
#include "stdio.h"
#define kp 33 //33
#define ki 0.12 //0.12
#define kd 6.5
#define SCLK PBout(13)
#define CS PBout(11)
#define DIN PBout(15)
char tempdata[4]={0,0,'.',0};
float set_temper=40;
float temp;
float temp1;
float temp2;
float out;
float DA_Value;
struct PID spid ; // PID Control Structure
char pid[3];
float e1,e2;
float temp_kpi=0;
float rout;
float rout1;
float rout2;
float rout3;
float out1;
float out2;
float tranDA=0;
void fuzzypid(float ew,float ec,char *pid)
{
char ee,ecec,i,j;
char eec[][7]=
{
-3,-2,-1,0,1,2,3,
-3,-2,-1,0,1,2,3
};
char KpRule[7][7]= //KpμÄÄ£oy¿ØÖƱí
{3,3,3,2,1,0,0,
3,3,2,2,1,0,-1,
3,3,2,1,0,-1,-1,
2,2,1,0,0,-1,-2,
1,1,0,-1,-1,-2,-2,
1,1,-1,-2,-2,-3,-3,
-1,-1,-2,-2,-3,-3,-3};
char KiRule[7][7]= //KpμÄÄ£oy¿ØÖƱí
{-3,-3,-2,-2,-1,-1,0,
-3,-3,-2,-1,-1,0,0,
-3,-2,-1,-1,0,1,2,
-2,-1,-1,0,0,1,2,
-2,-1,0,1,2,2,3,
0,0,0,1,2,2,3,
0,0,1,2,3,3,3,};
char KdRule[7][7]= //KpμÄÄ£oy¿ØÖƱí
{1,-1,-3,-3,-2,-2,1,
1,-1,-3,-2,-2,-1,0,
0,-1,-2,-2,-1,0,0,
0,0,-1,-1,-1,0,-1,
-1,-1,-1,0,0,0,0,
3,1,1,1,1,2,3,
3,3,2,2,1,1,3};
if(ew>=0)ee=ew*0.6+0.5;
else ee=-(fabs(ew*0.6)+0.5);//???
if(ec>=0)ecec=ec*10+0.5;
else ecec=-(fabs(ec*10)+0.5);
for(j=0;j<7;j++)
{
if(eec[0][j]==ee)break;
}
for(i=0;i<7;i++)
{
if(eec[1][i]==ecec)break;
}
pid[0]=KpRule[i][j];
pid[1]=KiRule[i][j];
pid[2]=KdRule[i][j];
}
void compare_temper()
{
float temp_kpi=0;
rout = PIDCalc ( &spid,temp1 );
rout2 = rout + rout1;
rout1=rout;
if (e1<-5) e1=-5;
else if(e1<=5);
else e1=5;
if (e2<-0.3) e2=-0.3;
else if(e2<=0.3);
else e2=0.3;
fuzzypid(e1,e2,pid);
temp_kpi=pid[0];
spid.Proportion=kp+temp_kpi*1;
temp_kpi=pid[1];
spid.Integral =ki+temp_kpi*0.01;
temp_kpi=pid[2];
spid.Derivative =kd+temp_kpi*0.1;
}
int main(void)
{
u8 t=0;
short temperature;
LED_Init();//LED3õê¼»ˉ
KEY_Init();//°′¼ü3õê¼»ˉ
SysTick_Init();//Ñóê±3õê¼»ˉ
USART1_Int(9600);
Dac1_Init();
SPI2_Init();
PIDInit ( &spid ); // Initialize Structure
spid.Proportion = kp; // Set PID Coefficients
spid.Integral = ki;
spid.Derivative =kd;
spid.Setval = set_temper;
LCD_Init();
printf(" LCD DS18B20 ζèÏÔê¾r");
POINT_COLOR=GREEN;
LCD_ShowString(40,20,200,16,16,"STM32");
LCD_ShowString(40,40,200,16,16,"DS18B20 ");
LCD_ShowString(40,60,200,20,16,"mengfangang biyesheji");
LCD_ShowString(40,80,200,16,16,"zhidaolaoshi gaohongyan");
while(DS18B20_Init()) //DS18B203õê¼»ˉ
{ POINT_COLOR=RED;
LCD_ShowString(40,100,200,16,16,"DS18B20 Error");
Delay_ms(200);
LCD_Fill(60,130,239,130+16,BROWN);
Delay_ms(200);
}
POINT_COLOR=RED;
LCD_ShowString(40,120,200,16,16,"DS18B20 OK");
POINT_COLOR=BLUE;//éèÖÃ×ÖìåÎaà¶é«
LCD_ShowString(40,160,200,16,16,"Temperate: . C");
LCD_ShowString(40,140,200,16,16,"set_temper: C");
LCD_ShowString(40,240,200,16,16,"rout: ");
LCD_ShowString(40,260,200,16,16,"rout1: ");
LCD_ShowString(40,280,200,16,16,"out: ");
while(1)
{
if(t%10==0)//ÿ100ms¶áè¡ò»′Î
{
temperature=DS18B20_Get_Temp();
temp1=temperature/10.0;
printf("%8.5f",temp1);
compare_temper() ;
out=rout2;
if(out>=2000)
{out1=2200;}
// else
// out1=rout;
// {if(1600<out&&out<2400)
// {out1=out*1.2;}
// else
// {if(1000<out&&out<1600)
// {out1=out*1.4;}
// else
// {if(800<out&&out<1000)
// {out1=out*1.8;}
// else
// { if(600<out&&out<800)
// {out1=out*1.5;}
// else
// { if(400<out&&out<600)
// {out1=out*3.5;}
// else
// {if(200<out&&out<400)
// {out1=out*7;}
// else
// {if(150<out&&out<200)
// {out1=out*7;}
// else
// { if(100<out&&out<150)
// {out1=out*10;}
else
// {if(100<out&&out<230)
// {out1=out*1.5;}
// else
//
{ if(0<out&&out<150)
{rout3=700;out1=out*10+rout3;}
}
// else
// {if(0>out)
// {out2=1800;}
// else
// out1=0;
// }
// }
// }
// }
// }
// }
// }
// }
// }
// }
// if(2500>rout&&rout>=1200)
// {out=2000;}
// else
// if(1200>rout&&rout>=900)
// { out=rout*2; }
//
// else
// if(900>rout&&rout>=0)
// { out=1950; }
// else
// out=1950;
// if(rout>=250)
// {out=1800;}
// else
// {
// if(250>rout&&rout>=120)
// {out=2600; }
// else
// {if(120>rout&&rout>=70)
// {out=2200; }
// else
// {
// if(70>rout&&rout>=50)
// {out=rout*30; }
// else
// {
// if(50>rout&&rout>=45)
// {out=rout*30; }
// else
// {
// if(45>rout&&rout>=35)
// { out=rout*30;}
// else
// { if(35>rout&&rout>=30)
// {out=rout*45;}
// else
// {if(29>rout&&rout>=25)
// {out=rout*60;}
// else
// {if(25>rout&&rout>=15)
// {out=rout*30;}
// else
//
// {if(15>rout&&rout>=0)
// {out=2400;}
// else
// {if(0>rout&&rout>=-15)
// {out=2300;}
//
// }
// }
//
// }
//
// }
//
// }
// }
// }
// }
// }
// }
if(temp1>41)
{Dac1_Set_Vol(0);}
else
{Dac1_Set_Vol(out1);}
if(temperature<0)
{
LCD_ShowChar(60+80,150,'-',16,0);
temperature=-temperature;
}
LCD_ShowChar(60+80,150,' ',16,0);
LCD_ShowNum(120+14,160,temperature/10,2,16);
LCD_ShowNum(140+16,160,temperature%10,2,16);
LCD_ShowNum(134,140,set_temper,2,16);
LCD_ShowNum(140+16,240,rout,5,16);
LCD_ShowNum(140+16,260,rout1,5,16);
LCD_ShowNum(140+16,280,out,5,16);
}
Delay_ms(10);
t++;
if(t==20)
{
t=0;
LED2_REV;
}
}
}
复制代码
作者:
IdeaMing
时间:
2020-7-21 10:13
有测个温度曲线吗?可以直观的看出来参数调整的效果如何
作者:
vm56321478
时间:
2020-7-25 01:35
有rule波型可以參考嗎?
作者:
jointech
时间:
2020-7-29 13:54
请问楼主批量测试过吗?
作者:
eddia2012
时间:
2020-8-15 22:09
思路好,下下来测试下,谢谢楼主!
作者:
来生只想做头猪
时间:
2021-9-1 17:23
源码可否给打包一个
作者:
seanking
时间:
2021-9-2 10:34
呵呵,最好有配套的电路描述,采样部分做的不好误差比较大
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1