当前位置:   article > 正文

PMSM磁场定向控制程序笔记(二)——Clark,Park及反变换_foc sdk2.0

foc sdk2.0

程序来源:FOC SDK2.0

说明:在FOC SDK2.0的基础上稍稍修改,并做了一些注释,主要是为了记录总结收获。删掉或者注释了一些暂时用不到的功能。

下面是MC_Clarke_Park.c文件部分程序:

  1. #ifdef MAX_MODULATION_100_PER_CENT //100%占空比
  2. #define START_INDEX 63
  3. const u16 circle_limit_table[65]=
  4. {
  5. 32767,32390,32146,31907,31673,31444,31220,31001,30787,30577,30371,
  6. 30169,29971,29777,29587,29400,29217,29037,28861,28687,28517,
  7. 28350,28185,28024,27865,27709,27555,27404,27256,27110,26966,
  8. 26824,26685,26548,26413,26280,26149,26019,25892,25767,25643,
  9. 25521,25401,25283,25166,25051,24937,24825,24715,24606,24498,
  10. 24392,24287,24183,24081,23980,23880,23782,23684,23588,23493,
  11. 23400,23307,23215,23125
  12. };
  13. #endif
  14. #define SIN_MASK 0x0300
  15. #define U0_90 0x0200
  16. #define U90_180 0x0300
  17. #define U180_270 0x0000
  18. #define U270_360 0x0100
  19. static Trig_Components Vector_Components;
  20. const s16 hSin_Cos_Table[256] = SIN_COS_TABLE; //正弦、余弦查表法
  21. /*******************************************************************************
  22. * Function Name : Clarke Transformation
  23. * Description : This function transforms stator currents qIas and
  24. * qIbs (which are directed along axes each displaced by
  25. * 120 degrees) into currents qIalpha and qIbeta in a
  26. * stationary qd reference frame.
  27. * qIalpha = qIas
  28. * qIbeta = -(2*qIbs+qIas)/sqrt(3)
  29. * Input : Stat_Curr_a_b
  30. * Output : Stat_Curr_alfa_beta
  31. * Return : none.
  32. *******************************************************************************/
  33. Curr_Components Clarke(Curr_Components Curr_Input)
  34. {
  35. Curr_Components Curr_Output;
  36. s32 qIa_divSQRT3_tmp;
  37. s32 qIb_divSQRT3_tmp ;
  38. s16 qIa_divSQRT3;
  39. s16 qIb_divSQRT3 ;
  40. // qIalpha = qIas
  41. Curr_Output.qI_Component1= Curr_Input.qI_Component1;
  42. qIa_divSQRT3_tmp = divSQRT_3 * Curr_Input.qI_Component1;
  43. qIa_divSQRT3_tmp /=32768; //相当于10*divsqrt(3)*Curr_Input.qI_Component1
  44. qIb_divSQRT3_tmp = divSQRT_3 * Curr_Input.qI_Component2;
  45. qIb_divSQRT3_tmp /=32768; //相当于10*divsqrt(3)*Curr_Input.qI_Component2
  46. qIa_divSQRT3=((s16)(qIa_divSQRT3_tmp));
  47. qIb_divSQRT3=((s16)(qIb_divSQRT3_tmp));
  48. //qIbeta = -(2*qIbs+qIas)/sqrt(3) beta轴滞后alpha轴,与常规不一样
  49. Curr_Output.qI_Component2=(-(qIa_divSQRT3)-(qIb_divSQRT3)-(qIb_divSQRT3));
  50. return(Curr_Output);
  51. }
  52. /*******************************************************************************
  53. * Function Name : Park Transformation
  54. * Description : This function transforms stator currents qIalpha and qIbeta,
  55. * which belong to a stationary qd reference frame, to a rotor
  56. * flux synchronous reference frame (properly oriented), so as
  57. * to obtain qIq and qIds.每转65535个脉冲
  58. * qId=qIalpha_tmp*sin(theta)+qIbeta_tmp*cos(Theta)
  59. * qIq=qIalpha_tmp*cos(Theta)-qIbeta_tmp*sin(Theta) 与常规不一样
  60. * Input : Stat_Curr_alfa_beta Theta是d与Beta之间的夹角
  61. * Output : Stat_Curr_q_d.
  62. * Return : Curr_Output.
  63. *******************************************************************************/
  64. Curr_Components Park(Curr_Components Curr_Input, s16 Theta)
  65. {
  66. Curr_Components Curr_Output;
  67. s32 qId_tmp_1, qId_tmp_2;
  68. s32 qIq_tmp_1, qIq_tmp_2;
  69. s16 qId_1, qId_2;
  70. s16 qIq_1, qIq_2;
  71. Vector_Components = Trig_Functions(Theta);
  72. //No overflow guaranteed
  73. qIq_tmp_1 = Curr_Input.qI_Component1 * Vector_Components.hCos;
  74. qIq_tmp_1 /= 32768;
  75. //No overflow guaranteed
  76. qIq_tmp_2 = Curr_Input.qI_Component2 *Vector_Components.hSin;
  77. qIq_tmp_2 /= 32768;
  78. qIq_1 = ((s16)(qIq_tmp_1));
  79. qIq_2 = ((s16)(qIq_tmp_2));
  80. //Iq component in Q1.15 Format
  81. Curr_Output.qI_Component1 = ((qIq_1)-(qIq_2));
  82. //No overflow guaranteed
  83. qId_tmp_1 = Curr_Input.qI_Component1 * Vector_Components.hSin;
  84. qId_tmp_1 /= 32768;
  85. //No overflow guaranteed
  86. qId_tmp_2 = Curr_Input.qI_Component2 * Vector_Components.hCos;
  87. qId_tmp_2 /= 32768;
  88. qId_1 = (s16)(qId_tmp_1);
  89. qId_2 = (s16)(qId_tmp_2);
  90. //Id component in Q1.15 Format
  91. Curr_Output.qI_Component2 = ((qId_1)+(qId_2));
  92. return (Curr_Output);
  93. }
  94. /*******************************************************************************
  95. * Function Name : RevPark_Circle_Limitation
  96. * Description : Check if
  97. * Stat_Volt_q_d.qV_Component1^2 + Stat_Volt_q_d.qV_Component2^2 <= 32767^2
  98. * Apply limitation if previous condition is not met,
  99. * by keeping a constant ratio
  100. * Stat_Volt_q_d.qV_Component1/Stat_Volt_q_d.qV_Component2
  101. * 将经过PID调节后的Vd,Vq映射到0-32767,对应的占空比位0-100%
  102. * 这就设计到合成矢量取模运算,即sqrt(Vd^2+Vq^2);
  103. * 运算量比较大,查表法
  104. * Input : None
  105. * Output : None
  106. * Return : None
  107. *******************************************************************************/
  108. void RevPark_Circle_Limitation(void)
  109. {
  110. s32 temp;
  111. temp = Stat_Volt_q_d.qV_Component1 * Stat_Volt_q_d.qV_Component1
  112. + Stat_Volt_q_d.qV_Component2 * Stat_Volt_q_d.qV_Component2; // min value 0, max value 2*32767*32767
  113. if ( temp > (u32)(( MAX_MODULE * MAX_MODULE) ) ) // (Vd^2+Vq^2) > MAX_MODULE^2 ´大于最大调制比
  114. {
  115. u16 index;
  116. temp /= (u32)(512*32768); // min value START_INDEX, max value 127
  117. temp -= START_INDEX ; // min value 0, max value 127 - START_INDEX
  118. //减去一个索引值,是因为前面的值都是32768,没有意义,存了浪费时间
  119. index = circle_limit_table[(u8)temp]; //index = MMI*S16_Max^2/V_magnitude_index
  120. temp = (s16)Stat_Volt_q_d.qV_Component1 * (u16)(index); //(Vq1)*MMI*S16_Max/V_mag
  121. Stat_Volt_q_d.qV_Component1 = (s16)(temp/32768); //Vq=(Vq1)*MMI*S16_Max/(32768*V_mag)
  122. temp = (s16)Stat_Volt_q_d.qV_Component2 * (u16)(index); //(Vd1)*MMI*S16_Max^2/V_mag
  123. Stat_Volt_q_d.qV_Component2 = (s16)(temp/32768); //Vd=(Vd1)*MMI*S16_Max/(32768*V_mag)
  124. }
  125. }
  126. /*******************************************************************************
  127. * Function Name : Rev_Park Transformation
  128. * Description : This function transforms stator voltage qVq and qVd, that
  129. * belong to a rotor flux synchronous rotating frame, to a
  130. * stationary reference frame, so as to obtain qValpha and qVbeta
  131. * qValfa=qVq*Cos(theta)+qVd*Sin(theta)
  132. * qVbeta=-qVq*Sin(theta)+qVd*Cos(theta)
  133. * Input : Stat_Volt_q_d.
  134. * Output : Stat_Volt_a_b
  135. * Return : none.
  136. *******************************************************************************/
  137. Volt_Components Rev_Park(Volt_Components Volt_Input)
  138. {
  139. s32 qValpha_tmp1,qValpha_tmp2,qVbeta_tmp1,qVbeta_tmp2;
  140. s16 qValpha_1,qValpha_2,qVbeta_1,qVbeta_2;
  141. Volt_Components Volt_Output;
  142. //No overflow guaranteed
  143. qValpha_tmp1 = Volt_Input.qV_Component1 * Vector_Components.hCos;
  144. qValpha_tmp1 /= 32768;
  145. qValpha_tmp2 = Volt_Input.qV_Component2 * Vector_Components.hSin;
  146. qValpha_tmp2 /= 32768;
  147. qValpha_1 = (s16)(qValpha_tmp1);
  148. qValpha_2 = (s16)(qValpha_tmp2);
  149. Volt_Output.qV_Component1 = ((qValpha_1)+(qValpha_2));
  150. qVbeta_tmp1 = Volt_Input.qV_Component1 * Vector_Components.hSin;
  151. qVbeta_tmp1 /= 32768;
  152. qVbeta_tmp2 = Volt_Input.qV_Component2 * Vector_Components.hCos;
  153. qVbeta_tmp2 /= 32768;
  154. qVbeta_1 = (s16)(qVbeta_tmp1);
  155. qVbeta_2 = (s16)(qVbeta_tmp2);
  156. Volt_Output.qV_Component2 = -(qVbeta_1)+(qVbeta_2);
  157. return(Volt_Output);
  158. }
  159. /*******************************************************************************
  160. * Function Name : Trig_Functions
  161. * Description : This function returns Cosine and Sine functions of the input
  162. * angle
  163. * 该函数根据输入角返回三角余弦和正弦函数值
  164. * Input : angle in s16 format
  165. * Output : Cosine and Sine in s16 format
  166. * Return : none.
  167. *******************************************************************************/
  168. Trig_Components Trig_Functions(s16 hAngle)
  169. {
  170. u16 hindex;
  171. Trig_Components Local_Components;
  172. /* 10 bit index computation */
  173. hindex = (u16)(hAngle + 32768);
  174. hindex /= 64;
  175. switch (hindex & SIN_MASK)
  176. {
  177. case U0_90:
  178. Local_Components.hSin = hSin_Cos_Table[(u8)(hindex)];
  179. Local_Components.hCos = hSin_Cos_Table[(u8)(0xFF-(u8)(hindex))];
  180. break;
  181. case U90_180:
  182. Local_Components.hSin = hSin_Cos_Table[(u8)(0xFF-(u8)(hindex))];
  183. Local_Components.hCos = -hSin_Cos_Table[(u8)(hindex)];
  184. break;
  185. case U180_270:
  186. Local_Components.hSin = -hSin_Cos_Table[(u8)(hindex)];
  187. Local_Components.hCos = -hSin_Cos_Table[(u8)(0xFF-(u8)(hindex))];
  188. break;
  189. case U270_360:
  190. Local_Components.hSin = -hSin_Cos_Table[(u8)(0xFF-(u8)(hindex))];
  191. Local_Components.hCos = hSin_Cos_Table[(u8)(hindex)];
  192. break;
  193. default:
  194. break;
  195. }
  196. return (Local_Components);
  197. }
今天就能理解到这儿了,还有很多不理解的地方,改天继续。加油!


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/247966
推荐阅读
相关标签
  

闽ICP备14008679号