foc_algorithm.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /**********************************
  2. * 文件名称: foc_algorithm.c
  3. * 功能描述: 磁场定向控制(FOC)算法实现
  4. * 主要功能:
  5. * 1. Clarke变换(三相到两相静止坐标系)
  6. * 2. Park变换(两相静止到两相旋转坐标系)
  7. * 3. 反Park变换(两相旋转到两相静止坐标系)
  8. * 4. SVPWM(空间矢量脉宽调制)计算
  9. * 5. 电流PID控制
  10. * 6. 电压限制
  11. * 7. EKF(扩展卡尔曼滤波器)状态估计
  12. * 8. 电感和电阻/磁链参数识别
  13. **********************************/
  14. #include "main.h"
  15. #include "foc_algorithm.h"
  16. // 电流PID控制器参数
  17. // 注:Vq和Vd是控制器输出,用于控制电机的q轴和d轴电压
  18. // Iq和Id是反馈电流,分别控制电机的转矩和磁场
  19. // 控制器参数通过自动调优获得
  20. real32_T D_PI_I = 200.F; // D轴积分系数
  21. real32_T D_PI_KB = 1.0F; // D轴反馈系数
  22. real32_T D_PI_ISUM_MAX = 12.0f; // D轴最大积分限幅
  23. real32_T D_PI_ISUM_MIN = -12.0f; // D轴最小积分限幅
  24. real32_T D_PI_LOW_LIMIT = -24.0F; // D轴输出下限
  25. real32_T D_PI_P = 1.0F; // D轴比例系数
  26. real32_T D_PI_UP_LIMIT = 24.0F; // D轴输出上限
  27. real32_T Q_PI_I = 200.F; // Q轴积分系数
  28. real32_T Q_PI_ISUM_MAX = 12.0f; // Q轴最大积分限幅
  29. real32_T Q_PI_ISUM_MIN = -12.0f; // Q轴最小积分限幅
  30. real32_T Q_PI_KB = 1.0F; // Q轴反馈系数
  31. real32_T Q_PI_LOW_LIMIT = -24.0F; // Q轴输出下限
  32. real32_T Q_PI_P = 1.0F; // Q轴比例系数
  33. real32_T Q_PI_UP_LIMIT = 24.0F; // Q轴输出上限
  34. /***************************************
  35. * Clarke变换
  36. * 功能:将三相电流转换为alpha-beta坐标系电流
  37. * 描述:将120度三相坐标系转换为90度两相静止坐标系
  38. ***************************************/
  39. void Clarke_Transf(CURRENT_ABC_DEF Current_abc_temp,CURRENT_ALPHA_BETA_DEF* Current_alpha_beta_temp)
  40. {
  41. Current_alpha_beta_temp->Ialpha = (Current_abc_temp.Ia - (Current_abc_temp.Ib + Current_abc_temp.Ic) * 0.5F) * 2.0F / 3.0F;
  42. Current_alpha_beta_temp->Ibeta = (Current_abc_temp.Ib - Current_abc_temp.Ic) * 0.866025388F * 2.0F / 3.0F;
  43. }
  44. /***************************************
  45. * SVPWM计算
  46. * 功能:将alpha-beta电压转换为PWM占空比
  47. * 描述:根据alpha-beta电压向量计算SVPWM占空比
  48. ***************************************/
  49. void SVPWM_Calc(VOLTAGE_ALPHA_BETA_DEF v_alpha_beta_temp,real32_T Udc_temp,real32_T Tpwm_temp)
  50. {
  51. int32_T sector;
  52. real32_T Tcmp1,Tcmp2,Tcmp3,Tx,Ty,f_temp,Ta,Tb,Tc;
  53. sector = 0;
  54. Tcmp1 = 0.0F;
  55. Tcmp2 = 0.0F;
  56. Tcmp3 = 0.0F;
  57. // 确定扇区,根据Vbeta和Valpha的值计算
  58. if (v_alpha_beta_temp.Vbeta > 0.0F) {
  59. sector = 1;
  60. }
  61. if ((1.73205078F * v_alpha_beta_temp.Valpha - v_alpha_beta_temp.Vbeta) / 2.0F > 0.0F) {
  62. sector += 2;
  63. }
  64. if ((-1.73205078F * v_alpha_beta_temp.Valpha - v_alpha_beta_temp.Vbeta) / 2.0F > 0.0F) {
  65. sector += 4;
  66. }
  67. // 根据扇区计算Tx和Ty
  68. switch (sector) {
  69. case 1:
  70. Tx = (-1.5F * v_alpha_beta_temp.Valpha + 0.866025388F * v_alpha_beta_temp.Vbeta) * (Tpwm_temp / Udc_temp);
  71. Ty = (1.5F * v_alpha_beta_temp.Valpha + 0.866025388F * v_alpha_beta_temp.Vbeta) * (Tpwm_temp / Udc_temp);
  72. break;
  73. case 2:
  74. Tx = (1.5F * v_alpha_beta_temp.Valpha + 0.866025388F * v_alpha_beta_temp.Vbeta) * (Tpwm_temp / Udc_temp);
  75. Ty = -(1.73205078F * v_alpha_beta_temp.Vbeta * Tpwm_temp / Udc_temp);
  76. break;
  77. case 3:
  78. Tx = -((-1.5F * v_alpha_beta_temp.Valpha + 0.866025388F * v_alpha_beta_temp.Vbeta) * (Tpwm_temp / Udc_temp));
  79. Ty = 1.73205078F * v_alpha_beta_temp.Vbeta * Tpwm_temp / Udc_temp;
  80. break;
  81. case 4:
  82. Tx = -(1.73205078F * v_alpha_beta_temp.Vbeta * Tpwm_temp / Udc_temp);
  83. Ty = (-1.5F * v_alpha_beta_temp.Valpha + 0.866025388F * v_alpha_beta_temp.Vbeta) * (Tpwm_temp / Udc_temp);
  84. break;
  85. case 5:
  86. Tx = 1.73205078F * v_alpha_beta_temp.Vbeta * Tpwm_temp / Udc_temp;
  87. Ty = -((1.5F * v_alpha_beta_temp.Valpha + 0.866025388F * v_alpha_beta_temp.Vbeta) * (Tpwm_temp / Udc_temp));
  88. break;
  89. default:
  90. Tx = -((1.5F * v_alpha_beta_temp.Valpha + 0.866025388F * v_alpha_beta_temp.Vbeta) * (Tpwm_temp / Udc_temp));
  91. Ty = -((-1.5F * v_alpha_beta_temp.Valpha + 0.866025388F * v_alpha_beta_temp.Vbeta) * (Tpwm_temp / Udc_temp));
  92. break;
  93. }
  94. // 归一化处理
  95. f_temp = Tx + Ty;
  96. if (f_temp > Tpwm_temp) {
  97. Tx /= f_temp;
  98. Ty /= (Tx + Ty);
  99. }
  100. // 计算各相占空比
  101. Ta = (Tpwm_temp - (Tx + Ty)) / 4.0F;
  102. Tb = Tx / 2.0F + Ta;
  103. Tc = Ty / 2.0F + Tb;
  104. // 根据扇区分配占空比
  105. switch (sector) {
  106. case 1:
  107. Tcmp1 = Tb;
  108. Tcmp2 = Ta;
  109. Tcmp3 = Tc;
  110. break;
  111. case 2:
  112. Tcmp1 = Ta;
  113. Tcmp2 = Tc;
  114. Tcmp3 = Tb;
  115. break;
  116. case 3:
  117. Tcmp1 = Ta;
  118. Tcmp2 = Tb;
  119. Tcmp3 = Tc;
  120. break;
  121. case 4:
  122. Tcmp1 = Tc;
  123. Tcmp2 = Tb;
  124. Tcmp3 = Ta;
  125. break;
  126. case 5:
  127. Tcmp1 = Tc;
  128. Tcmp2 = Ta;
  129. Tcmp3 = Tb;
  130. break;
  131. case 6:
  132. Tcmp1 = Tb;
  133. Tcmp2 = Tc;
  134. Tcmp3 = Ta;
  135. break;
  136. }
  137. // 更新FOC输出
  138. FOC_Output.Tcmp1 = Tcmp1;
  139. FOC_Output.Tcmp2 = Tcmp2;
  140. FOC_Output.Tcmp3 = Tcmp3;
  141. }
  142. /***************************************
  143. * 角度转余弦正弦值
  144. * 功能:将角度转换为余弦和正弦值
  145. * 描述:使用ARM DSP库计算角度的余弦和正弦值
  146. ***************************************/
  147. void Angle_To_Cos_Sin(real32_T angle_temp,TRANSF_COS_SIN_DEF* cos_sin_temp)
  148. {
  149. cos_sin_temp->Cos = arm_cos_f32(angle_temp);
  150. cos_sin_temp->Sin = arm_sin_f32(angle_temp);
  151. }
  152. /***************************************
  153. * Park变换
  154. * 功能:将alpha-beta坐标系电流转换为DQ坐标系电流
  155. * 描述:使用余弦和正弦值将两相静止坐标系转换为两相旋转坐标系
  156. ***************************************/
  157. void Park_Transf(CURRENT_ALPHA_BETA_DEF current_alpha_beta_temp,TRANSF_COS_SIN_DEF cos_sin_temp,CURRENT_DQ_DEF* current_dq_temp)
  158. {
  159. current_dq_temp->Id = current_alpha_beta_temp.Ialpha * cos_sin_temp.Cos + current_alpha_beta_temp.Ibeta * cos_sin_temp.Sin;
  160. current_dq_temp->Iq = -current_alpha_beta_temp.Ialpha * cos_sin_temp.Sin + current_alpha_beta_temp.Ibeta * cos_sin_temp.Cos;
  161. }
  162. /***************************************
  163. * 反Park变换
  164. * 功能:将DQ坐标系电压转换为alpha-beta坐标系电压
  165. * 描述:使用余弦和正弦值将两相旋转坐标系转换为两相静止坐标系
  166. ***************************************/
  167. void Rev_Park_Transf(VOLTAGE_DQ_DEF v_dq_temp,TRANSF_COS_SIN_DEF cos_sin_temp,VOLTAGE_ALPHA_BETA_DEF* v_alpha_beta_temp)
  168. {
  169. v_alpha_beta_temp->Valpha = cos_sin_temp.Cos * v_dq_temp.Vd - cos_sin_temp.Sin * v_dq_temp.Vq;
  170. v_alpha_beta_temp->Vbeta = cos_sin_temp.Sin * v_dq_temp.Vd + cos_sin_temp.Cos * v_dq_temp.Vq;
  171. }
  172. /***************************************
  173. * 电流PID控制器
  174. * 功能:计算电流PID控制器输出
  175. * 描述:根据参考值和反馈值计算PID控制器输出
  176. ***************************************/
  177. void Current_PID_Calc(real32_T ref_temp, real32_T fdb_temp,
  178. real32_T* out_temp, CURRENT_PID_DEF* pid)
  179. {
  180. real32_T err = ref_temp - fdb_temp;
  181. real32_T p_out = pid->P_Gain * err;
  182. real32_T i_out = pid->I_Gain * pid->I_Sum;
  183. real32_T pre_out = p_out + i_out;
  184. real32_T output;
  185. if (pre_out > pid->Max_Output) {
  186. output = pid->Max_Output;
  187. } else if (pre_out < pid->Min_Output) {
  188. output = pid->Min_Output;
  189. } else {
  190. output = pre_out;
  191. }
  192. if ((pre_out <= pid->Max_Output && pre_out >= pid->Min_Output) ||
  193. (err* (output - pre_out) <= 0)) {
  194. pid->I_Sum += err * FOC_PERIOD;
  195. }
  196. // if (pid->I_Sum > pid->Max_Integral) pid->I_Sum = pid->Max_Integral;
  197. // if (pid->I_Sum < pid->Min_Integral) pid->I_Sum = pid->Min_Integral;
  198. // vd = R*id + Ld*(did/dt) - ωe*Lq*iq // 电压方程
  199. // vq = R*iq + Lq*(diq/dt) + ωe*Ld*id + ωe*λm
  200. *out_temp = output;
  201. }
  202. /***************************************
  203. * 电压限制
  204. * 功能:限制电压向量幅值
  205. * 描述:确保电压向量不超过SVPWM的最大幅值
  206. ***************************************/
  207. void voltage_limit(float *vd, float *vq, float vdc)
  208. {
  209. float vmax = vdc * 0.57735f; // 计算SVPWM的最大电压幅值
  210. float v_sq = (*vd)*(*vd) + (*vq)*(*vq);
  211. if (v_sq > vmax*vmax) {
  212. float scale = vmax / sqrtf(v_sq);
  213. *vd *= scale;
  214. *vq *= scale;
  215. }
  216. }