foc_task.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "hal/hal.h"
  2. #include "hal/pwm.h"
  3. #include "libs/task.h"
  4. #include "foc_task.h"
  5. #include "foc.h"
  6. #include "phase_current.h"
  7. #include "park_clark.h"
  8. #include "hall_sensor.h"
  9. #include "svpwm.h"
  10. static void __inline foc_update_theta(motor_foc_t *foc) {
  11. float angle = 0.0f;
  12. if (foc->override.is_theta) {
  13. angle = foc->override.theta;
  14. }else {
  15. angle = hall_sensor_get_theta();
  16. }
  17. foc->motor_s.theta = degree_2_pi(angle);
  18. }
  19. /* 输出dq电压给反park,最后给svpwm */
  20. static void __inline Foc_Dq_PI_Contrl(motor_foc_t *foc, dq_t *sampled, dq_t *ref_out) {
  21. if (foc->mode == FOC_MODE_PI_DQ || foc->mode == FOC_MODE_PI_FULL) {
  22. ref_out->d = pi_control(&foc->PI_id, foc->dq_ref.d - sampled->d);
  23. ref_out->q = pi_control(&foc->PI_iq, foc->dq_ref.q - sampled->q);
  24. }else {
  25. ref_out->d = foc->dq_ref.d;
  26. ref_out->q = foc->dq_ref.q;
  27. }
  28. if (foc->override.is_vdq) {
  29. ref_out->d = foc->override.vdq.d;
  30. ref_out->q = foc->override.vdq.q;
  31. }
  32. }
  33. static void __inline DeadTime_Compensation(current_samp_t *c_sample, phase_time_t *time) {
  34. /* Dead time compensation */
  35. if ( c_sample->ia > 0)
  36. {
  37. time->A += TDead;
  38. }
  39. else
  40. {
  41. time->A -= TDead;
  42. }
  43. if ( c_sample->ib > 0 )
  44. {
  45. time->B += TDead;
  46. }
  47. else
  48. {
  49. time->B -= TDead;
  50. }
  51. if ( c_sample->ic > 0 )
  52. {
  53. time->C += TDead;
  54. }
  55. else
  56. {
  57. time->C -= TDead;
  58. }
  59. }
  60. /* FOC 主控制逻辑 */
  61. void FOC_Fast_Task(motor_foc_t *foc){
  62. current_samp_t *c_sample = &foc->current_samp;
  63. alpha_beta_t sample_ab, pwm_ab;
  64. dq_t sample_dq, v_dq;
  65. phase_time_t phase_time;
  66. u32 sample_point;
  67. /* 更新电角度 */
  68. foc_update_theta(foc);
  69. /* 采集3相电流 */
  70. phase_current_sample(c_sample);
  71. /* ABC坐标转alpha-beta坐标 */
  72. Clark(c_sample->ia, c_sample->ib, c_sample->ic, &sample_ab);
  73. /* alpha-beta坐标转旋转坐标系D-Q */
  74. Park(&sample_ab, foc->motor_s.theta, &sample_dq);
  75. /* 处理D,Q电流环,速度环低频运行,不在此处处理*/
  76. Foc_Dq_PI_Contrl(foc, &sample_dq, &v_dq);
  77. /* d-q坐标转 alpha-beta坐标,输入给pwm */
  78. Rev_Park(&v_dq, foc->motor_s.theta, &pwm_ab);
  79. /* 生成 pwm,模拟正弦波,此处vbus需要动态采集 */
  80. svpwm(&pwm_ab, foc->vbus, FOC_PWM_Half_Period, &phase_time, &foc->sector);
  81. /* 通过扇区和pwm duty 选择合适的3相电流采样点 */
  82. sample_point = get_phase_sample_point(c_sample, &phase_time, foc->sector);
  83. /* 死区补偿 */
  84. DeadTime_Compensation(c_sample, &phase_time);
  85. /* 更新duty和采样点到硬件TIM1中 */
  86. PWM_UpdateDuty(phase_time.A, phase_time.B, phase_time.C, sample_point);
  87. }
  88. //输出dq电流,给电流环
  89. static void __inline Foc_Speed_PI_Control(motor_foc_t *foc) {
  90. if (foc->mode == FOC_MODE_PI_SPEED || foc->mode == FOC_MODE_PI_FULL){
  91. float speed_ref = ramp_get_target(&foc->speed_ramp);
  92. float vq_out = pi_control(&foc->PI_speed, speed_ref - foc->motor_s.rpm);
  93. foc->dq_ref.q = vq_out;
  94. }
  95. }
  96. void FOC_Normal_Task(motor_foc_t *foc) {
  97. switch (foc->state) {
  98. case START:
  99. PWM_TurnOnLowSides();
  100. FOC_STM_NextState(CURRENT_CALIBRATE);
  101. break;
  102. case CURRENT_CALIBRATE:
  103. foc_current_calibrate();
  104. FOC_STM_NextState(READY_TO_RUN);
  105. break;
  106. case READY_TO_RUN:
  107. foc_pwm_start(true);
  108. FOC_STM_NextState(RAMPING_START);
  109. ramp_exc(&foc->start_ramp);
  110. foc_overide_vdq(true);
  111. break;
  112. case RAMPING_START:
  113. foc_overide_set_vdq(0.0f, ramp_get_target(&foc->start_ramp));
  114. if (ramp_complete(&foc->start_ramp)) {
  115. FOC_STM_NextState(RUNNING);
  116. }
  117. break;
  118. case RUNNING:
  119. Foc_Speed_PI_Control(foc);
  120. break;
  121. case ANY_STOP:
  122. ramp_clear(&foc->start_ramp);
  123. foc_clear();
  124. FOC_STM_NextState(IDLE);
  125. break;
  126. default:
  127. break;
  128. }
  129. }