SRF-PLL c语言实现
时间: 2023-08-03 11:08:41 浏览: 60
SRF-PLL(Selective Resonant Frequency Phase Locked Loop)是一种用于电力电子系统中的谐波检测和滤波的技术。以下是一个简单的SRF-PLL的C语言实现示例,供您参考:
```c
#define PI 3.141592653589793
struct srf_pll {
double Ts; // 采样时间
double T; // 滤波器时间常数
double wn; // 自然频率
double zeta; // 阻尼比
double alpha; // 系数alpha
double beta; // 系数beta
double gamma; // 系数gamma
double delta; // 系数delta
double theta_prev; // 上一次的相位角
double v_q_prev; // 上一次的Q轴电压
double v_d_prev; // 上一次的D轴电压
};
void srf_pll_init(struct srf_pll *pll, double Ts, double T, double wn, double zeta)
{
pll->Ts = Ts;
pll->T = T;
pll->wn = wn;
pll->zeta = zeta;
pll->alpha = T * T * wn * wn;
pll->beta = 2 * T * wn * zeta;
pll->gamma = T * T * wn * wn + 2 * T * wn * zeta + 1 / (Ts * Ts);
pll->delta = 2 * T * wn * zeta + 1 / (Ts * Ts);
pll->theta_prev = 0;
pll->v_q_prev = 0;
pll->v_d_prev = 0;
}
double srf_pll_update(struct srf_pll *pll, double v_q, double v_d)
{
double v_qf, v_df, v_qd, v_dd, e, theta, theta_diff;
// 一阶低通滤波
v_qf = (1 - pll->alpha) * pll->v_q_prev + pll->alpha * v_q;
v_df = (1 - pll->alpha) * pll->v_d_prev + pll->alpha * v_d;
// 偏差计算
v_qd = v_qf - pll->v_d_prev;
v_dd = v_df + pll->v_q_prev;
e = pll->beta * v_qd - pll->delta * v_dd;
// 相位角计算
theta = pll->theta_prev + 2 * PI * pll->wn * pll->Ts * (pll->gamma * pll->theta_prev + e);
theta_diff = theta - pll->theta_prev;
if (theta_diff > PI)
theta_diff -= 2 * PI;
else if (theta_diff < -PI)
theta_diff += 2 * PI;
pll->theta_prev = theta;
// 保存上一次的状态
pll->v_q_prev = v_qf;
pll->v_d_prev = v_df;
return theta_diff / (2 * PI * pll->Ts);
}
```
在上面的代码中,`srf_pll`结构体包含了各种参数和状态变量。在初始化时,需要指定采样时间`Ts`、滤波器时间常数`T`、自然频率`wn`和阻尼比`zeta`。在每次更新时,Q轴和D轴电压被输入到PLL中,计算出相位角差,并返回归一化后的结果。其中,一阶低通滤波器和偏差计算使用了标准的PI控制器,相位角计算则使用了SRF-PLL的公式。
使用时,可以按照以下方式初始化SRF-PLL对象并进行更新:
```c
struct srf_pll pll;
double theta_diff;
srf_pll_init(&pll, Ts, T, wn, zeta);
theta_diff = srf_pll_update(&pll, v_q, v_d);
```
其中,`Ts`是采样时间,`T`是滤波器时间常数,`wn`是自然频率,`zeta`是阻尼比,`v_q`和`v_d`是输入的Q轴和D轴电压,`theta_diff`是输出的相位角差。需要根据具体应用场景选择合适的参数。