miniFOC 1.0.3
This open-source project aims to accomplish a FOC(Field Oriented Control) scheme that is operatable with minimum costs in China.
foc.c
Go to the documentation of this file.
1/**************************************************************************/
10#include "foc.h"
11#include "config.h"
12#include "fast_math.h"
13#include "encoder.h"
14#include "system.h"
15#include "timer.h"
16
24volatile unsigned char phase_sequence = 0;
29
34 unsigned short last_angle = 0, positive_counter = 0;
35 float u, v, w, angle = 0;
36
37 /* set that there is only a magnetic field on the straight axis */
38 foc_calculate_dutycycle(0, CALI_TORQUE, 0, &u, &v, &w);
39 update_pwm_dutycycle(u, v, w);
40 delayms(1000);
41
42 for (unsigned char counter = 0; counter < 50; ++counter) {
43 /* measure current motor angle */
44 unsigned short current_angle = encoder_get_mechanical_angle();
45
46 /* judge whether the current angle increases */
47 if (current_angle > last_angle)
48 positive_counter++;
49
50 /* update last angle as current angle */
51 last_angle = current_angle;
52
53 /* set that there is only a magnetic field on the straight axis */
54 foc_calculate_dutycycle(angle, CALI_TORQUE, 0, &u, &v, &w);
55 angle += 0.2f;
56 update_pwm_dutycycle(u, v, w);
57 delayms(20);
58 }
59 for (unsigned char counter = 0; counter < 50; ++counter) {
60 /* measure current motor angle */
61 unsigned short current_angle = encoder_get_mechanical_angle();
62
63 /* judge whether the current angle decreases */
64 if (current_angle < last_angle)
65 positive_counter++;
66
67 /* update last angle as current angle */
68 last_angle = current_angle;
69
70 /* set that there is only a magnetic field on the straight axis */
71 foc_calculate_dutycycle(angle, CALI_TORQUE, 0, &u, &v, &w);
72 angle -= 0.2f;
73 update_pwm_dutycycle(u, v, w);
74 delayms(20);
75 }
76
77 /* zero the torque in all directions to release the motor */
78 foc_calculate_dutycycle(0, 0, 0, &u, &v, &w);
79 update_pwm_dutycycle(u, v, w);
80 delayms(300);
81
82 if (positive_counter >= 75)
84 else if (positive_counter < 25)
86 else
87 while (1);
88}
89
99void foc_calculate_dutycycle(float elect_angle, float d, float q, float *u, float *v, float *w) {
100 float alpha, beta;
101
102 /* fast calculation of cosine and sine value of electric angle */
103 float cf = fast_cos(elect_angle);
104 float sf = fast_sin(elect_angle);
105
106#if USE_SVPWM == 0
107 /* firstly, the inverse Park transform is calculated */
108 alpha = d * cf - q * sf;
109 beta = q * cf + d * sf;
110
111 /* secondly, the inverse Clarke transform is calculated */
112 *u = 0.5f - alpha / VBUS;
113 *v = 0.5f + (alpha * 0.5f - beta * 0.866025404f) / VBUS;
114 *w = 1.5f - *u - *v;
115#else
116 float tmp2, tmp3, Ta, Tb, Tc;
117 char vec_sector = 3;
118
119 /* firstly, the inverse Clarke transform is calculated */
120 alpha = d * cf - q * sf;
121 beta = q * cf + d * sf;
122 tmp2 = beta * 0.5f + alpha * 0.8660254f;
123 tmp3 = tmp2 - beta;
124
125 /* judge which sector the magnetic vector is in at this time */
126 vec_sector = ((*(unsigned int *) &tmp2) >> 31) ? vec_sector : (vec_sector - 1);
127 vec_sector = ((*(unsigned int *) &tmp3) >> 31) ? vec_sector : (vec_sector - 1);
128 vec_sector = ((*(unsigned int *) &beta) >> 31) ? (7 - vec_sector) : vec_sector;
129
130 /* the proportion of each phase is calculated by six sector modulation method */
131 switch (vec_sector) {
132 case 1:
133 case 4: Ta = tmp2;
134 Tb = beta - tmp3;
135 Tc = -tmp2;
136 break;
137 case 2:
138 case 5:Ta = tmp3 + tmp2;
139 Tb = beta;
140 Tc = -beta;
141 break;
142 default:Ta = tmp3;
143 Tb = -tmp3;
144 Tc = -(beta + tmp2);
145 break;
146 }
147
148 /* calculate the duty cycle in center alignment mode */
149 *u = (Ta / VBUS) * 0.5f + 0.5f;
150 *v = (Tb / VBUS) * 0.5f + 0.5f;
151 *w = (Tc / VBUS) * 0.5f + 0.5f;
152#endif
153}
used to place important parameter configurations for users
#define CALI_TORQUE
set calibrate torque to 0.5
Definition: config.h:19
#define VBUS
bus voltage is 8.0V
Definition: config.h:13
unsigned short encoder_get_mechanical_angle(void)
read mechanical angle directly from encoder
Definition: encoder.c:76
this is the header file of encoder.c.
float fast_sin(float theta)
fast calculation of sine
Definition: fast_math.c:72
this is the header file of fast_math.c, the macros of fast amplitude limiting algorithm and cosine fu...
#define fast_cos(x)
fast calculation of cosine
Definition: fast_math.h:27
void foc_calculate_dutycycle(float elect_angle, float d, float q, float *u, float *v, float *w)
calculate the corresponding three-phase PWM duty cycle under the current electrical angle
Definition: foc.c:99
unsigned char foc_parameter_available_flag
flag variable for FOC parameter availability
Definition: foc.c:28
volatile FOC_Structure_t FOC_Struct
FOC handler.
Definition: foc.c:20
void foc_calibrate_phase(void)
automatic phase sequence detection and correction
Definition: foc.c:33
volatile unsigned char phase_sequence
motor phase sequence flag variable
Definition: foc.c:24
this is the header file of foc.c, which defines the structure of FOC algorithm and angle conversion f...
structure of FOC algorithm
Definition: foc.h:17
void delayms(unsigned long count)
millisecond delay function, any time time.
Definition: system.c:30
system basic function header file
void update_pwm_dutycycle(float ch0, float ch1, float ch2)
update timer1 ch0 1 2 duty-cycle
Definition: timer.c:20
this is the header file of timer.c.