foc_task.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #include "hal/hal.h"
  2. #include "hal/pwm.h"
  3. #include "foc_task.h"
  4. #include "phase_current.h"
  5. #include "park_clark.h"
  6. #include "hall_sensor.h"
  7. #include "svpwm.h"
  8. static void __inline foc_update_theta(motor_foc_t *foc) {
  9. float angle = 0.0f;
  10. if (foc->override_p.is_override_theta) {
  11. angle = foc->override_p.theta;
  12. }else {
  13. angle = hall_sensor_get_theta();
  14. }
  15. foc->motor_s.theta = degree_2_pi(angle);
  16. }
  17. static void __inline foc_update_PI_Contrl(motor_foc_t *foc, dq_t *sampled, dq_t *ref_out) {
  18. if (foc->mode == FOC_MODE_PI_DQ || foc->mode == FOC_MODE_PI_FULL) {
  19. ref_out->d = pi_control(&foc->PI_id, foc->dq_ref.d - sampled->d);
  20. ref_out->q = pi_control(&foc->PI_iq, foc->dq_ref.q - sampled->q);
  21. }else {
  22. ref_out->d = foc->dq_ref.d;
  23. ref_out->q = foc->dq_ref.q;
  24. }
  25. if (foc->override_p.is_override_v_dq) {
  26. ref_out->d = foc->override_p.v_dq.d;
  27. ref_out->q = foc->override_p.v_dq.q;
  28. }
  29. }
  30. void foc_task(motor_foc_t *foc){
  31. current_samp_t *c_sample = &foc->current_samp;
  32. alpha_beta_t sample_ab, pwm_ab;
  33. dq_t sample_dq, v_dq;
  34. phase_time_t phase_time;
  35. u32 sample_point;
  36. /* 更新电角度 */
  37. foc_update_theta(foc);
  38. /* 采集3相电流 */
  39. phase_current_sample(c_sample);
  40. /* ABC坐标转alpha-beta坐标 */
  41. Clark(c_sample->ia, c_sample->ib, c_sample->ic, &sample_ab);
  42. /* alpha-beta坐标转旋转坐标系D-Q */
  43. Park(&sample_ab, foc->motor_s.theta, &sample_dq);
  44. /* 处理D,Q电流环,速度环低频运行,不在此处处理*/
  45. foc_update_PI_Contrl(foc, &sample_dq, &v_dq);
  46. /* d-q坐标转 alpha-beta坐标,输入给pwm */
  47. Rev_Park(&v_dq, foc->motor_s.theta, &pwm_ab);
  48. /* 生成 pwm,模拟正弦波,此处vbus需要动态采集 */
  49. svpwm(&pwm_ab, foc->vbus, FOC_PWM_Half_Period, &phase_time, &foc->sector);
  50. /* 通过扇区和pwm duty 选择合适的3相电流采样点 */
  51. sample_point = get_phase_sample_point(c_sample, &phase_time, foc->sector);
  52. /* 更新duty和采样点到硬件TIM1中 */
  53. PWM_UpdateDuty(phase_time.A, phase_time.B, phase_time.C, sample_point);
  54. }