日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言pID程序怎么设计,51单片机PID的算法实现程序C语言

發布時間:2025/3/12 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言pID程序怎么设计,51单片机PID的算法实现程序C语言 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

#include typedef unsigned char uint8;

typedef unsigned int uint16;

typedef unsigned long int uint32;

/函數聲明/

void PIDOutput ();

void PIDOperation ();

/*/

typedef struct PIDValue

{

uint32 Ek_Uint32[3]; //差值保存,給定和反饋的差值

uint8 EkFlag_Uint8[3]; //符號,1則對應的為負數,0為對應的為正數

uint8 KP_Uint8;

uint8 KI_Uint8;

uint8 KD_Uint8;

uint16 Uk_Uint16; //上一時刻的控制電壓

uint16 RK_Uint16; //設定值

uint16 CK_Uint16; //實際值

}PIDValueStr;

PIDValueStr PID;

uint8 out ; // 加熱輸出

uint8 count; // 輸出時間單位計數器

/*

PID = Uk + KP*[E(k)-E(k-1)]+KI*E(k)+KD*[E(k)-2E(k-1)+E(k-2)];(增量型PID算式)

函數入口: RK(設定值),CK(實際值),KP,KI,KD

函數出口: U(K)

//PID運算函數

/

void PIDOperation (void)

{

uint32 Temp[3]; //中間臨時變量

uint32 PostSum; //正數和

uint32 NegSum; //負數和

Temp[0] = 0;

Temp[1] = 0;

Temp[2] = 0;

PostSum = 0;

NegSum = 0;

if( PID.RK_Uint16 > PID.RK_Uint16 ) //設定值大于實際值否?

{

if( PID.RK_Uint16 - PID.RK_Uint16 >10 ) //偏差大于10否?

{

PID.Uk_Uint16 = 100; //偏差大于10為上限幅值輸出(全速加熱)

}

else

{

Temp[0] = PID.RK_Uint16 - PID.CK_Uint16; //偏差<=10,計算E(k)

PID.EkFlag_Uint8[1]=0; //E(k)為正數

//數值移位

PID.Ek_Uint32[2] = PID.Ek_Uint32[1];

PID.Ek_Uint32[1] = PID.Ek_Uint32[0];

PID.Ek_Uint32[0] = Temp[0];

//

if( PID.Ek_Uint32[0] >PID.Ek_Uint32[1] ) //E(k)>E(k-1)否?

{

Temp[0]=PID.Ek_Uint32[0] - PID.Ek_Uint32[1]; //E(k)>E(k-1)

PID.EkFlag_Uint8[0]=0; //E(k)-E(k-1)為正數

}

else

{

Temp[0]=PID.Ek_Uint32[0] - PID.Ek_Uint32[1]; //E(k)PID.EkFlag_Uint8[0]=1; //E(k)-E(k-1)為負數

}

//

Temp[2]=PID.Ek_Uint32[1]*2 ; // 2E(k-1)

if( (PID.Ek_Uint32[0]+ PID.Ek_Uint32[2])>Temp[2] ) //E(k-2)+E(k)>2E(k-1)否?

{

Temp[2]=(PID.Ek_Uint32[0]+ PID.Ek_Uint32[2])-Temp[2]; //E(k-2)+E(k)>2E(k-1)

PID.EkFlag_Uint8[2]=0; //E(k-2)+E(k)-2E(k-1)為正數

}

else

{

Temp[2]=Temp[2]-(PID.Ek_Uint32[0]+ PID.Ek_Uint32[2]); //E(k-2)+E(k)<2E(k-1)

PID.EkFlag_Uint8[2]=1; //E(k-2)+E(k)-2E(k-1)為負數

}

//

Temp[0] = (uint32)PID.KP_Uint8 * Temp[0]; // KP*[E(k)-E(k-1)]

Temp[1] = (uint32)PID.KI_Uint8 * PID.Ek_Uint32[0]; // KI*E(k)

Temp[2] = (uint32)PID.KD_Uint8 * Temp[2]; // KD*[E(k-2)+E(k)-2E(k-1)]

/*以下部分代碼是講所有的正數項疊加,負數項疊加*/

/KP*[E(k)-E(k-1)]/

if(PID.EkFlag_Uint8[0]==0)

PostSum += Temp[0]; //正數和

else

NegSum += Temp[0]; //負數和

/* KI*E(k)/

if(PID.EkFlag_Uint8[1]==0)

PostSum += Temp[1]; //正數和

else

; //空操作,E(K)>0

/KD*[E(k-2)+E(k)-2E(k-1)]/

if(PID.EkFlag_Uint8[2]==0)

PostSum += Temp[2]; //正數和

else

NegSum += Temp[2]; //負數和

/*U(K)*/

PostSum += (uint32)PID.Uk_Uint16;

if(PostSum > NegSum ) // 是否控制量為正數

{

Temp[0] = PostSum - NegSum;

if( Temp[0] < 100 ) //小于上限幅值則為計算值輸出

PID.Uk_Uint16 = (uint16)Temp[0];

else

PID.Uk_Uint16 = 100; //否則為上限幅值輸出

}

else //控制量輸出為負數,則輸出0(下限幅值輸出)

PID.Uk_Uint16 = 0;

}

}

else

{

PID.Uk_Uint16 = 0;

}

}

/*

函數入口: U(K)

函數出口: out(加熱輸出)

//PID運算植輸出函數

/

void PIDOutput (void)

{

static int i;

i=PID.Uk_Uint16;

if(i==0)

out=1;

else out=0;

if((count++)==5)//如定時中斷為40MS,40MS*5=0.2S(輸出時間單位),加熱周期20S(100等份)

{ //每20S PID運算一次

count=0;

i--;

}

}本文引用地址:http://www.eepw.com.cn/article/201611/318566.htm

總結

以上是生活随笔為你收集整理的c语言pID程序怎么设计,51单片机PID的算法实现程序C语言的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。