前言:上个月预告要推出对ST的高频注入代码解读,后面看了下代码,一言难尽。。。
机缘巧合之下,有位朋友给出了另外一份代码,那就拿这个填坑吧~~~
简介:本文采用的是方波注入的方式,并非脉振,注入电压的幅值是标幺值0.3,注入方波的频率和PWM频率成线性关系,最后选取750Hz.
知乎文章修改字体比较麻烦,也不能改变颜色,以下代码中文注释即为我的解读,阅读不便望理解。
/*高频注入主函数,ZLSPD表示zero and low speed position detection*/
/***************************************************************
* High Frequency Injection - Implementation
***************************************************************/
void ZLSPD(HPF *iq, HPF_COEFF *k, HFI *h, NS_ID *n, CLARKE *i, PHASEVOLTAGE *v)
{
static _iq kp,
dIq,
IqOld,
thetaErr,
volt_hfi;
static Uint16 Squ_PRD,
squ_cnt,
NS_cnt;
/*在复位状态机下,复位角度误差,采样记录的Iq,方波幅值,计数器等关键信息*/
/********************************************
* Reset State
********************************************/
if(h->HFI_Status == HFI_RESET_STATE)
{
NS_cnt = 0;
thetaErr = 0;
IqOld = 0;
dIq = 0;
squ_cnt = 0;
Squ_PRD = h->Squ_PRD_set;
volt_hfi = h->volt_ipd;
kp = h->Kp_IPD;
// HPF_RESET(iq); // reset HPF
h->HFI_Status = HFI_IPD_STATE; // Start HFI
}
/*如果在磁极辨识状态机下,则调用NS_Determination函数完成对磁极的辨识*/
/********************************************
* NS state
********************************************/
else if(h->HFI_Status == HFI_NSID_STATE)
{
NS_Determination(n,h,i);
}
/*状态机处于高频注入计算状态下*/
/********************************************
* HFI IPD and RUN states
********************************************/
else
{
/*提取q轴高频电流分量,作为角度误差*/
// HPF_MODULE(id, k); /* HPF on phase current to extract HF component */
HPF_MODULE(iq, k); /* HPF on phase current to extract HF component */
/*脉宽计数,多个开关周期组成一个正向方波激励*/
/*******************************
* Square wave period control
*******************************/
if (Squ_PRD != h->Squ_PRD_set)
{
if (Squ_PRD < h->Squ_PRD_set)
Squ_PRD++;
else
Squ_PRD--;
}
/*记录脉冲电流顶点和底点两处的Iq,中间的略去不需要。把顶点到底点的电流变化量作为
方波激励产生的电流变化,即对应角度偏移产生的q轴脉冲电流误差,同时翻转方波极性*/
/****************************************************
* Square wave polarity control + angle error calc
****************************************************/
if (++squ_cnt >= Squ_PRD)
{
squ_cnt = 0;
dIq = SIGN(h->dutyMax) * (iq->Out - IqOld); /* angle error */
IqOld = iq->Out;
h->dutyMax = -h->dutyMax; /* Square wave polarity control */
/*在辨识初始位置和低速HFI观测两个不同的阶段,使用的电压幅值,PLL或者PI的带宽是不同的*/
/******************************
* Initial HFI for IPD state
******************************/
if (NS_cnt < h->HFI_Time2) //400
{
/* Initial alignment estimation */
if (++NS_cnt < h->HFI_Time1) //300
{
volt_hfi = h->volt_ipd; //80
kp = h->Kp_IPD;
}
/* clear motor currents to prep for NSID */
else if (NS_cnt < h->HFI_Time2)
{
volt_hfi = 0;
}
/* set state to NSID */
else
h->HFI_Status = HFI_NSID_STATE;
}
/*********************************
* Post IPD HFI for RUN state
*********************************/
else
{
volt_hfi = h->volt_run;
kp = h->Kp_RUN;
}
}
/*q轴高频电流分量直接与角度线性相关,拿到了角度误差,通过锁相环或者PI
调节器计算出了速度,速度积分获得了角度,角度超过2pi则翻转*/
/************************************************************/
/* Angle estimation */
/************************************************************/
thetaErr = dIq;
h->speedEst = _IQmpy(kp, thetaErr);
h->thetaEst += _IQmpy(h->speedEst, h->base_wTs); //
ANGLE_WRAP(h->thetaEst);
/*当BUS电压低于注入电压,则需要限制注入电压幅值*/
/************************************************************/
/* Duty cycle (HFI Square wave mag) estimation */
/************************************************************/
/* volt1.DcBusVolt = _IQ12toIQ(AdcResult.ADCRESULT7); */
if (v->DcBusVolt < volt_hfi)
h->duty = h->dutyMax;
else
h->duty = _IQdiv(_IQmpy(h->dutyMax, volt_hfi), v->DcBusVolt);
}
return;
}
代码的思路和上一篇文章完全是吻合的,方波HFI其实可调的东西并不多,关键在于一些细节的处理,和对电机凸极性的理解。
受限于资源,代码不是很详细,能够详细解读的地方有限,希望大家理解。