三相锁相环仿真及其代码验证,附C语言源码
2020-07-18 04:27
781 查看
三相锁相环仿真及其代码验证,附C语言源码
各种变换
众所周知,三相电的锁相环只需要进行Clark变换和Park变换得到dq分量,进行PI运算就可以轻松的完成锁相,这里就不简述Clark变换和Park变换了,网上一搜一大把资料
仿真
源码
主要代码
// // Included Files // #include <math.h> #include "Interrupt.h" /* ABC电压值变量定义 */ FLOAT32 g_f32Ua; FLOAT32 g_f32Ub; FLOAT32 g_f32Uc; typedef struct STRUCT_SPLL { /* input data */ FLOAT32 g_f32VoltD; FLOAT32 g_f32VoltQ; FLOAT32 g_f32Theta; /* output data */ FLOAT32 g_f32SinWT; FLOAT32 g_f32CosWT; /* parameter */ FLOAT32 g_f32VoltAlpha; FLOAT32 g_f32VoltBeta; PI_CONTROL_STRUCT PllLoop; }ST_SPLL; /* 锁相环PI控制 */ #define PLL_MAX_OUT 2000 #define PLL_MIN_OUT -2000 #define PLL_KP 48.0 * 2.0//12 // 0.3 #define PLL_KI 0.1 * 2.0//0.04 // 0.001 ST_SPLL g_stSpll = {0}; UINT16 g_u16VoltageIndex = 0; UINT16 g_u16SendFlag = 0; FLOAT32 g_f32VoltageSample[3] = {0}; void ISR_APP_ThreePhaseSPLL(ST_SPLL *t_spll, const FLOAT32 *VABC, UINT32 Ts); //中断频率50k #pragma CODE_SECTION(ISR_InterruptTask, ".TI.ramfunc"); __interrupt void ISR_InterruptTask(void) { g_u16VoltageIndex++; if(g_u16VoltageIndex > 1000) g_u16VoltageIndex = 0; g_f32VoltageSample[0] = sinf(2 * M_PI * 100 / 1000 * g_u16VoltageIndex);//模拟输出A相电压,可由adc采样值替换 g_f32VoltageSample[1] = sinf(2 * M_PI * 100 / 1000 * g_u16VoltageIndex - 2*M_PI/3.0f);//模拟输出B相电压 g_f32VoltageSample[2] = sinf(2 * M_PI * 100 / 1000 * g_u16VoltageIndex + 2*M_PI/3.0f);//模拟输出C相电压 g_f32Ua = g_f32VoltageSample[0]; g_f32Ub = g_f32VoltageSample[1]; g_f32Uc = g_f32VoltageSample[2]; ISR_APP_ThreePhaseSPLL(&g_stSpll, g_f32VoltageSample, 1000);//锁相环函数 } void APP_InitSpll(ST_SPLL *t_spll) { t_spll->g_f32VoltD = 0; t_spll->g_f32VoltQ = 0; t_spll->g_f32Theta = 0; /* output data */ t_spll->g_f32SinWT = 0; t_spll->g_f32CosWT = 0; /* parameter */ t_spll->g_f32VoltAlpha = 0; t_spll->g_f32VoltBeta = 0; t_spll->PllLoop.m_u16CtrFlg = INCREMENTAL_CONTROL; /* 增量式PI控制标志 */ t_spll->PllLoop.m_f32Ref = 0; /* 给定 */ t_spll->PllLoop.m_f32Fed = 0; /* 反馈 */ t_spll->PllLoop.m_f32Err = 0; /* 误差 */ t_spll->PllLoop.m_f32ErrPre = 0; /* 前拍误差 */ t_spll->PllLoop.m_f32Kp = PLL_KP; /* 比例参数 */ t_spll->PllLoop.m_f32Ki = PLL_KI; /* 积分参数 */ t_spll->PllLoop.m_f32Acc = 0; /* 积分累加 */ t_spll->PllLoop.m_f32LoopOut = 0; /* 输出 */ t_spll->PllLoop.m_f32KiMaxACC = PLL_MAX_OUT; /* 积分累加最大限幅 */ t_spll->PllLoop.m_f32KiMinACC = PLL_MIN_OUT; /* 积分累加最小限幅 */ t_spll->PllLoop.m_f32MaxOutput = PLL_MAX_OUT; /* 输出最大限幅 */ t_spll->PllLoop.m_f32MinOutput = PLL_MIN_OUT; /* 输出最小限幅 */ } #pragma CODE_SECTION(ISR_APP_ABC2ab, ".TI.ramfunc"); void ISR_APP_ThreePhaseSPLL(ST_SPLL *t_spll, const FLOAT32 *VABC, UINT32 Ts) { FLOAT32 t_f32TempValue = 0; t_spll->g_f32VoltAlpha = 0.6666667f * (VABC[0]-(0.5f*VABC[1])-(0.5*VABC[2]));//Clark变换 t_spll->g_f32VoltBeta = 0.6666667f*(((sqrtf(3)/2)*VABC[1])-((sqrtf(3)/2)*VABC[2])); #if 0 //开环 theta = 2 * M_PI * 50; #endif //Park变换 t_spll->g_f32VoltD = t_spll->g_f32CosWT * t_spll->g_f32VoltAlpha + t_spll->g_f32SinWT * t_spll->g_f32VoltBeta; t_spll->g_f32VoltQ = -t_spll->g_f32SinWT * t_spll->g_f32VoltAlpha + t_spll->g_f32CosWT * t_spll->g_f32VoltBeta; //锁相环环路计算 t_spll->PllLoop.m_f32Ref = t_spll->g_f32VoltD;//0; t_spll->PllLoop.m_f32Fed = 0;//t_spll->g_f32VoltD; t_spll->PllLoop.m_f32Err = t_spll->PllLoop.m_f32Ref - t_spll->PllLoop.m_f32Fed; t_f32TempValue = t_spll->PllLoop.m_f32Ki * t_spll->PllLoop.m_f32Err; /* 积分计算 */ t_f32TempValue += t_spll->PllLoop.m_f32Kp * (t_spll->PllLoop.m_f32Err - t_spll->PllLoop.m_f32ErrPre); /* 比例计算 */ t_spll->PllLoop.m_f32LoopOut += t_f32TempValue;/* 增量运算 */ t_spll->PllLoop.m_f32ErrPre = t_spll->PllLoop.m_f32Err; if (t_spll->PllLoop.m_f32LoopOut > t_spll->PllLoop.m_f32MaxOutput) /* 输出限幅 */ { t_spll->PllLoop.m_f32LoopOut = t_spll->PllLoop.m_f32MaxOutput; } if (t_spll->PllLoop.m_f32LoopOut < t_spll->PllLoop.m_f32MinOutput) { t_spll->PllLoop.m_f32LoopOut = t_spll->PllLoop.m_f32MinOutput; } t_spll->g_f32Theta += (t_spll->PllLoop.m_f32LoopOut / Ts);//环路输出即为w,需要t积分 if(t_spll->g_f32Theta > (2 * M_PI)) { t_spll->g_f32Theta = t_spll->g_f32Theta - (2 * M_PI); } if(t_spll->g_f32Theta < 0) { t_spll->g_f32Theta = t_spll->g_f32Theta + (2 * M_PI); } t_spll->g_f32SinWT = sinf(t_spll->g_f32Theta); t_spll->g_f32CosWT = cosf(t_spll->g_f32Theta); } // // End of File //
相关文章推荐
- Scala 深入浅出实战经典 第48讲:Scala类型约束代码实战及其在Spark中的应用源码解析
- 微信云控系统的实现原理,微信云控系统源码之服务器推送的实现及其核心代码
- C语言总复习第一阶段部分练习题及其代码
- 从U-Boot源码看C语言对汇编代码中的符号引用
- 47.Scala多重界定代码实战及其在Spark中的应用源码解析
- scala-43:Scala中类型变量Bounds代码实战及其在Spark中的应用源码解析
- 第43讲:Scala中类型变量Bounds代码实战及其在Spark中的应用源码解析
- setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT) 功能的验证 及其 源码实现分析
- C语言与OC中常见的字符串函数及其代码和使用
- 排序算法之堆排序<Heap_Sort>及其C语言代码实现
- 第44讲:Scala中View Bounds代码实战及其在Spark中的应用源码解析学习笔记
- 46.ClassTag 、Manifest、ClassManifest、TypeTag代码实战及其在Spark中的应用源码解析
- 第47讲:Scala多重界定代码实战及其在Spark中的应用源码解析学习笔记
- Scala中View Bounds代码实战及其在Spark中的应用源码解析之Scala学习笔记-35
- 第44讲:Scala中View Bounds代码实战及其在Spark中的应用源码解析
- Scala深入浅出进阶经典 第44讲:Scala中View Bounds代码实战及其在Spark中的应用源码解析
- Scala中Variance代码实战及其在Spark中的应用源码解析之Scala学习笔记-40
- 源码推荐(01.20B):JS与OC中Webview交互, 两行代码搞定TouchID验证
- 从U-Boot源码看C语言对汇编代码中的符号引用
- 排序算法之插入排序<Insertion_Sort>及其C语言代码实现