FocControlFunction.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #include <Myproject.h>
  2. void FOC_Init(void)
  3. {
  4. DRV_CMR = 0x0ABF;
  5. // 使能FOC
  6. ClrBit(DRV_CR, DRVEN);
  7. ClrBit(DRV_CR, FOCEN);
  8. SetBit(DRV_CR, FOCEN);
  9. SetBit(FOC_CR0, MERRS1 | MERRS0);
  10. FOC_EOMEKLPF = 0xff; //速度滤波系数,值越小滤波深度越深
  11. FOC_KFG = 0; //FG计算系数 = 6M(TIM4分频结果)/640(FBase)
  12. // 配置FOC寄存器
  13. FOC_CR1 = 0;
  14. FOC_CR2 = 0;
  15. FOC_IDREF = 0;
  16. FOC_IQREF = 0;
  17. FOC__THETA = 0;
  18. FOC_RTHEACC = 0;
  19. FOC__RTHESTEP = 0;
  20. FOC_RTHECNT = 0;
  21. FOC_THECOR = 0x02; // 误差角度补偿
  22. // 电流环参数配置
  23. FOC_DKP = DQKP;
  24. FOC_DKI = DQKI;
  25. FOC_QKP = DQKP;
  26. FOC_QKI = DQKI;
  27. FOC_ID_LPFK = 250;
  28. FOC_IQ_LPFK = 250;
  29. FOC_DMAX = DOUTMAX;
  30. FOC_DMIN = DOUTMIN;
  31. FOC_QMAX = QOUTMAX;
  32. FOC_QMIN = QOUTMIN;
  33. SetBit(FOC_CR0, ESCMS);
  34. // 估算器配置
  35. #if (EstimateAlgorithm == SMO)
  36. {
  37. ClrBit(FOC_CR2, ESEL);
  38. ClrBit(FOC_CR3, MFP_EN);
  39. }
  40. #elif (EstimateAlgorithm == AO)
  41. {
  42. SetBit(FOC_CR3, MFP_EN);
  43. ClrBit(FOC_CR2, ESEL);
  44. }
  45. #elif (EstimateAlgorithm == PLL)
  46. {
  47. ClrBit(FOC_CR3, MFP_EN);
  48. SetBit(FOC_CR2, ESEL);
  49. FOC_KSLIDE = OBSE_PLLKP_GAIN1;
  50. FOC_EKLPFMIN = OBSE_PLLKI_GAIN1;
  51. }
  52. #endif
  53. FOC_EK1 = OBS_K1T;
  54. FOC_EK2 = OBS_K2T;
  55. FOC_EK3 = OBS_K3T;
  56. FOC_EK4 = OBS_K4T;
  57. FOC_KSLIDE = OBS_KSLIDE;
  58. FOC_EKLPFMIN = OBS_EA_KS;
  59. FOC_FBASE = OBS_FBASE;
  60. FOC_OMEKLPF = SPEED_KLPF;
  61. FOC_TGLI = PWM_TGLI_LOAD;
  62. SetBit(FOC_CR1, SVPWMEN);
  63. // 转向配置
  64. #if (IRMODE)
  65. SetBit(DRV_CR, DDIR);
  66. #else
  67. ClrBit(DRV_CR, DDIR);
  68. #endif
  69. // 过调制
  70. #if (OverModulation)
  71. SetBit(FOC_CR1, OVMDL);
  72. #endif
  73. // 单电阻采样;需要最小采样窗,FOC_TRGDLY为0,七段式SVPWM方式
  74. #if (Shunt_Resistor_Mode == Single_Resistor)
  75. {
  76. SetReg(FOC_CR1, CSM0 | CSM1, 0x00);
  77. FOC_TSMIN = PWM_TS_LOAD; // 最小采样窗口
  78. FOC_TRGDLY = 0x3B; // 采样时刻在中点,一般考虑开关噪声影响,会设置延迟;3B
  79. SetReg(FOC_CR2, CSOC0 | CSOC1, 0x00);
  80. FOC_CSO = currOffset.IwBusOffset;
  81. }
  82. // 双电阻采样,可设置死区补偿值,在下降沿结束前开始采样Ia,配置81
  83. #elif (Shunt_Resistor_Mode == Double_Resistor)
  84. {
  85. SetReg(FOC_CR1, CSM0 | CSM1, CSM0);
  86. FOC_TSMIN = PWM_DT_LOAD; // 死区补偿值
  87. FOC_TRGDLY = 0x05; // ADC采样的时刻,采样时刻在计数器零点附近,83为下降沿结束前3个clock采样Ia,与单电阻不同
  88. // 01为上升沿开始后第一个clock开始采样。根据实际情况调整。
  89. FOC_TBLO = PWM_DLOWL_TIME; //下桥臂最小脉冲,保证采样
  90. SetReg(FOC_CR2, CSOC0 | CSOC1, CSOC0);
  91. FOC_CSO = currOffset.IuOffset;
  92. SetReg(FOC_CR2, CSOC0 | CSOC1, CSOC1);
  93. FOC_CSO = currOffset.IvOffset;
  94. // 采样配置
  95. #if (DouRes_Sample_Mode == DouRes_1_Cycle)
  96. ClrBit(FOC_CR2, DSS);
  97. #elif (DouRes_Sample_Mode == DouRes_2_Cycle)
  98. SetBit(FOC_CR2, DSS);
  99. #endif
  100. }
  101. // 三电阻采样
  102. #elif (Shunt_Resistor_Mode == Three_Resistor)
  103. {
  104. SetReg(FOC_CR1, CSM0 | CSM1, CSM0 | CSM1);
  105. FOC_TSMIN = PWM_DT_LOAD; // 死区补偿值
  106. FOC_TRGDLY = 0x08; // ADC采样的时刻,采样时刻在计数器零点附近,83为下降沿结束前3个clock采样Ia,与单电阻不同。
  107. // 01为上升沿开始后第一个clock开始采样。根据实际情况调整。
  108. FOC_TBLO = PWM_OVERMODULE_TIME; // 过调制电流采样处理的TB脉宽
  109. // 采样配置
  110. #if (DouRes_Sample_Mode == DouRes_1_Cycle)
  111. ClrBit(FOC_CR2, DSS);
  112. #elif (DouRes_Sample_Mode == DouRes_2_Cycle)
  113. SetBit(FOC_CR2, DSS);
  114. #endif
  115. SetReg(FOC_CR2, CSOC0 | CSOC1, CSOC0);
  116. FOC_CSO = currOffset.IuOffset;
  117. SetReg(FOC_CR2, CSOC0 | CSOC1, CSOC1);
  118. FOC_CSO = currOffset.IvOffset;
  119. SetReg(FOC_CR2, CSOC0 | CSOC1, 0x00);
  120. FOC_CSO = currOffset.IwBusOffset;
  121. }
  122. #endif
  123. // SVPWM 配置
  124. #if (SVPMW_Mode == SVPWM_7_Segment)
  125. ClrBit(FOC_CR2, F5SEG);
  126. #elif (SVPMW_Mode == SVPWM_5_Segment)
  127. SetBit(FOC_CR2, F5SEG);
  128. #endif
  129. SetBit(DRV_CR, DRVEN);
  130. SetBit(DRV_CR, OCS);
  131. }
  132. /*---------------------------------------------------------------------------*/
  133. /* Name : void Motor_Align(void)
  134. /* Input : NO
  135. /* Output : NO
  136. /* Description: 预定位函数,当无逆风判断时,采用预定位固定初始位置;当有逆风判断时,采用预定位刹车
  137. /*---------------------------------------------------------------------------*/
  138. void Motor_Align(void)
  139. {
  140. if (McStaSet.SetFlag.AlignSetFlag == 0)
  141. {
  142. McStaSet.SetFlag.AlignSetFlag = 1;
  143. // FOC初始化
  144. FOC_Init();
  145. // 配置预定位的电流、KP、KI
  146. FOC_IDREF = 0;
  147. FOC_IQREF = 0;
  148. FOC_DKP = DQKP_Alignment;
  149. FOC_DKI = DQKI_Alignment;
  150. FOC_QKP = DQKP_Alignment;
  151. FOC_QKI = DQKI_Alignment;
  152. FOC_EKP = OBSW_KP_GAIN;
  153. FOC_EKI = OBSW_KI_GAIN;
  154. // 配置预定位角度
  155. #if (EstimateAlgorithm == SMO)
  156. FOC__ETHETA = FOC__THETA - 4836;
  157. #elif (EstimateAlgorithm == PLL)
  158. FOC__ETHETA = FOC__THETA;
  159. #endif
  160. DRV_CMR |= 0x03F;
  161. MOE = 1;
  162. }
  163. if (mcFocCtrl.State_Count > (AlignmentHoldTime1 + AlignmentHoldTime2))
  164. {
  165. mcFocCtrl.CurrentAlignStatus = 0;
  166. FOC__THETA = Align_Angle1;
  167. FOC_IQREF = ID_Align_CURRENT_End * (Align_Time - mcFocCtrl.State_Count) / AlignmentRampTime;
  168. }
  169. else if (mcFocCtrl.State_Count > AlignmentHoldTime2)
  170. {
  171. mcFocCtrl.CurrentAlignStatus = 1;
  172. FOC__THETA = Align_Angle1;
  173. FOC_IQREF = ID_Align_CURRENT_End;
  174. }
  175. else if (mcFocCtrl.State_Count > 0)
  176. {
  177. mcFocCtrl.CurrentAlignStatus = 2;
  178. FOC__THETA = Align_Angle2;
  179. FOC_IQREF = ID_Align_CURRENT_End;
  180. }
  181. else
  182. { mcState = mcStart; }
  183. }
  184. /*---------------------------------------------------------------------------*/
  185. /* Name : void Motor_Open(void)
  186. /* Input : NO
  187. /* Output : NO
  188. /* Description: 开环启动的参数配置
  189. /*---------------------------------------------------------------------------*/
  190. void Motor_Open(void)
  191. {
  192. static uint8 OpenRampCycles;
  193. // FOC_Init();
  194. // 启动角度
  195. // FOC__THETA = _Q15((float)0.0 / 180.0);
  196. #if ((EstimateAlgorithm == SMO)||(EstimateAlgorithm == AO))
  197. FOC__ETHETA = FOC__THETA - 4836; //SMO估算角度延迟
  198. #elif (EstimateAlgorithm == PLL)
  199. FOC__ETHETA = FOC__THETA;
  200. #endif
  201. FOC__EOME = 0;
  202. // 配置参数
  203. FOC_IDREF = 0;
  204. FOC_DKP = DQKPStart;
  205. FOC_DKI = DQKIStart;
  206. FOC_QKP = DQKPStart;
  207. FOC_QKI = DQKIStart;
  208. FOC_EKP = OBSW_KP_GAIN;
  209. FOC_EKI = OBSW_KI_GAIN;
  210. /// 启动方式选择
  211. #if (Open_Start_Mode == Omega_Start)
  212. {
  213. FOC_EFREQACC = MOTOR_OMEGA_RAMP_ACC;
  214. FOC_EFREQMIN = MOTOR_OMEGA_ACC_MIN;
  215. FOC_EFREQHOLD = MOTOR_OMEGA_ACC_END;
  216. SetReg(FOC_CR1, EFAE | RFAE | ANGM, EFAE | ANGM);
  217. #if (IFFDebugg)
  218. {
  219. // 估算器禁止输出
  220. ClrBit(FOC_CR1, EFAE); // 禁止估算器强制输出
  221. ClrBit(FOC_CR1, RFAE); // 使能强拉
  222. ClrBit(FOC_CR1, ANGM); // 禁止估算器输出
  223. }
  224. #endif
  225. // 切入启动
  226. mcFocCtrl.State_Count = 1200;
  227. mcState = mcRun;
  228. }
  229. #elif (Open_Start_Mode == Open_Start)
  230. {
  231. FOC_RTHEACC = MOTOR_OPEN_ACC;
  232. FOC__RTHESTEP = MOTOR_OPEN_ACC_MIN;
  233. FOC_RTHECNT = MOTOR_OPEN_ACC_CNT;
  234. SetReg(FOC_CR1, EFAE | RFAE | ANGM, RFAE);
  235. // 切入启动
  236. if (OpenRampCycles < (MOTOR_OPEN_ACC_CYCLE - 1))
  237. {
  238. if (!ReadBit(FOC_CR1, RFAE))
  239. {
  240. SetBit(FOC_CR1, RFAE);
  241. OpenRampCycles++;
  242. }
  243. }
  244. else
  245. {
  246. mcFocCtrl.State_Count = 2;
  247. mcState = mcRun;
  248. }
  249. FOC_EKP = OBSW_KP_GAIN_RUN4;
  250. FOC_EKI = OBSW_KI_GAIN_RUN4;
  251. }
  252. #elif (Open_Start_Mode == Open_Omega_Start)
  253. {
  254. FOC_RTHEACC = MOTOR_OPEN_ACC;
  255. FOC__RTHESTEP = MOTOR_OPEN_ACC_MIN;
  256. FOC_RTHECNT = MOTOR_OPEN_ACC_CNT;
  257. FOC_EFREQACC = Motor_OMEGA_RAMP_ACC;
  258. FOC_EFREQMIN = MOTOR_OMEGA_ACC_MIN;
  259. FOC_EFREQHOLD = MOTOR_OMEGA_ACC_END;
  260. SetReg(FOC_CR1, EFAE | RFAE | ANGM, EFAE | RFAE | ANGM);
  261. // 切入启动
  262. mcFocCtrl.State_Count = 2600;
  263. mcState = mcRun;
  264. }
  265. #endif
  266. // Q轴启动电流
  267. FOC_IQREF = IQ_Start_CURRENT ;
  268. }