看到有不少人問到底如何讓UK值與PWM佔空比值對應,進而實現佔空比輸出和輸出控制電壓對應。
(注意,我這裏討論的前提是輸出控制的是電壓,不是PWM方波。PWM輸出後要經過濾波整形再輸出控制。)
前提條件:
輸出電壓控制電壓範圍是0-10V。
給定、反饋、輸出電壓採樣輸入電壓範圍是0-5V(經過運放)。
使用單片機AD爲10位AD芯片。
那麼10位AD芯片電壓採集得到的數據範圍就是0-1024。
PWM爲 8位可調佔空比方波,0對應輸出佔空比爲0的方波,255對應輸出佔空比100%的方波,127對應輸出50%的方波。
比如當前給定是2.5V,反饋電壓是1V。(KP,KI,KD等係數略,關於PID算法的整數實現我在前文中有論述如何實現)。
那麼經過AD採樣
1、給定2.5V對應爲 512
2、反饋1V對應爲 205
假定經過PID計算得到的UK爲400
也就意味着輸出電壓應當爲(400*(UPWM峯值電壓))/1024
那麼UK對應的PWM佔空比是多少呢?
我們知道,UK=1024對應占空比爲100,也就是PWM的佔空比係數爲255。可知,PWM係數 = UK/4;
那麼400就應當對應係數 400/4=100。
也就是輸出電壓=400*10/1024=3.9V
同時,由於採樣精度以及PWM輸出佔空比精度控制的問題,將導致輸出電壓和期望值不是那麼線性,所以,我在項目內加入了輸出電壓採樣的控制。
採樣AD輸入爲0-5V,所以,對於輸出0-10V有一個縮小的比例。
輸出10V則採樣值對應爲255
輸出5V則採樣之對應127
可知,3.9V對應AD結果爲97
採樣輸出電壓值,可以針對性的調整一下佔空比輸出,從而得到誤差允許範圍內的一個控制輸出電壓。
同時,經過一些加速控制的手段。可以比較迅速的達到控制的目的。
下文中的UK控制方法是針對增量式PID控制而來做的。
/****************************************************/
void PWMProcess(void)
{
uint16 idata temp;
uint16 idata UKTemp;
temp = 0;
UKTemp = 0;
if( Pwm.ChangeFlag_Uint8 != 0 ) //判斷是否需要改變佔空比
{ //是否需要改變佔空比和你的被控系統特性有關
Pwm.ChangeFlag_Uint8 = 0;
UKTemp = PID.Uk_Uint16 + SwIn.AddValue_Uint16;
//計算UK控制量
//控制量和計算值以及一個開關量有關,我這裏的開關量是系統需要的時候疊加在控制量上的一個變量。
if(UKTemp>999)
{
UKTemp = 999;
}
//這裏只所以是999封頂而不是1024是因爲我的系統PWM的峯值電壓是12V導致。
while(1) //如果輸出電壓和期望電壓相差 Delta,則繼續調整佔空比,直到在誤差以內
{
ADChPro(UPWMADCH); //測量輸出電壓
if( ADPool.Value_Uint16[UPWMADCH] == UKTemp)
{
return;
}
if( ADPool.Value_Uint16[UPWMADCH] > UKTemp) //如果當前電壓大於輸出電壓,減小佔空比
{
if( ( ADPool.Value_Uint16[UPWMADCH] - UKTemp ) > UDELTA )
{
temp = ADPool.Value_Uint16[UPWMADCH] - UKTemp; //
temp = temp / 2; //下降可以加速下降,所以下降參數加倍
if( Pwm.DutyCycle_Uint8 > temp )
{
Pwm.DutyCycle_Uint8 = Pwm.DutyCycle_Uint8 - temp;
}
else
{
Pwm.DutyCycle_Uint8 = 0;
}
}
else
{
return;
}
}
else //如果當前電壓小於輸出電壓
{
if( ( UKTemp - ADPool.Value_Uint16[UPWMADCH] ) > UDELTA )
{
temp = UKTemp - ADPool.Value_Uint16[UPWMADCH];
temp = temp / 4; //上升處理不要超調,所以每次只+一半
if( (255-Pwm.DutyCycle_Uint8) > temp )
{
Pwm.DutyCycle_Uint8 += (temp/2);
}
else
{
Pwm.DutyCycle_Uint8 = 255;
}
}
else
{
return;
}
}
DisPlayVoltage();
PWMChangeDuty(Pwm.DutyCycle_Uint8); //改變佔空比
Delay(10,10);
}
}
}
/*****************************************************/