|
@@ -7,6 +7,15 @@
|
|
|
|
|
|
|
|
#define HALL_READ_TIMES 3
|
|
#define HALL_READ_TIMES 3
|
|
|
/*
|
|
/*
|
|
|
|
|
+* 测量HALL_PLACE_OFFSET通用方式就是ST推荐的通过外力带动电机,
|
|
|
|
|
+* 测量电机U相反电动势和hall 1的上升沿之间的差值
|
|
|
|
|
+* 这里使用的是先通过hall_sensor_calibrate测量hall1,2,3,4,5,6
|
|
|
|
|
+* 对应的角度(偏差比较大),然后启动电机,让HALL_PLACE_OFFSET
|
|
|
|
|
+* 从0开始增加,每增加1度观察电机电流(看直流电源),
|
|
|
|
|
+* 找到一个电机平稳转动并且电流最小的角度作为HALL_PLACE_OFFSET
|
|
|
|
|
+*/
|
|
|
|
|
+#define HALL_PLACE_OFFSET 207.0f
|
|
|
|
|
+/*
|
|
|
100
|
|
100
|
|
|
101
|
|
101
|
|
|
001
|
|
001
|
|
@@ -16,8 +25,7 @@
|
|
|
4,5,1,3,2,6,4
|
|
4,5,1,3,2,6,4
|
|
|
*/
|
|
*/
|
|
|
static u16 _hall_table[] = {0xFFFF, 292/*1*/, 54/*2*/, 1/*3*/, 180/*4*/, 229/*5*/, 115/*6*/, 0xFFFF};
|
|
static u16 _hall_table[] = {0xFFFF, 292/*1*/, 54/*2*/, 1/*3*/, 180/*4*/, 229/*5*/, 115/*6*/, 0xFFFF};
|
|
|
-//static u16 _hall_table[] = {0xFFFF, 292/*1*/, 65/*2*/, 7/*3*/, 185/*4*/, 250/*5*/, 116/*6*/, 0xFFFF};
|
|
|
|
|
-
|
|
|
|
|
|
|
+//static u16 _hall_table[] = {0xFFFF, 257/*1*/, 36/*2*/, 344/*3*/, 159/*4*/, 222/*5*/, 88/*6*/, 0xFFFF};
|
|
|
static hall_t _hall;
|
|
static hall_t _hall;
|
|
|
static hall_sample_t h_samples;
|
|
static hall_sample_t h_samples;
|
|
|
|
|
|
|
@@ -60,6 +68,9 @@ static float __inline _hall_avg_speed(void){
|
|
|
void hall_sensor_init(void) {
|
|
void hall_sensor_init(void) {
|
|
|
memset(&_hall, 0, sizeof(_hall));
|
|
memset(&_hall, 0, sizeof(_hall));
|
|
|
read_hall(_hall.state, _hall.theta);
|
|
read_hall(_hall.state, _hall.theta);
|
|
|
|
|
+#ifdef HALL_PLACE_OFFSET
|
|
|
|
|
+ _hall.phase_offset = HALL_PLACE_OFFSET;
|
|
|
|
|
+#endif
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
float hall_sensor_get_theta(void){
|
|
float hall_sensor_get_theta(void){
|
|
@@ -101,7 +112,7 @@ int hall_sensor_calibrate(float current, u16 *hall_table){
|
|
|
memset(sin_hall, 0, sizeof(sin_hall));
|
|
memset(sin_hall, 0, sizeof(sin_hall));
|
|
|
memset(cos_hall, 0, sizeof(cos_hall));
|
|
memset(cos_hall, 0, sizeof(cos_hall));
|
|
|
memset(hall_iterations, 0, sizeof(hall_iterations));
|
|
memset(hall_iterations, 0, sizeof(hall_iterations));
|
|
|
-
|
|
|
|
|
|
|
+ task_udelay(50 * 1000);
|
|
|
// Forwards
|
|
// Forwards
|
|
|
for (int i = 0;i < 3;i++) {
|
|
for (int i = 0;i < 3;i++) {
|
|
|
for (int j = 0;j < 360;j++) {
|
|
for (int j = 0;j < 360;j++) {
|
|
@@ -148,12 +159,107 @@ int hall_sensor_calibrate(float current, u16 *hall_table){
|
|
|
return fails == 2;
|
|
return fails == 2;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+#ifdef HALL_PLACE_OFFSET
|
|
|
void hall_sensor_handler(void) {
|
|
void hall_sensor_handler(void) {
|
|
|
u8 state_now = get_hall_stat(HALL_READ_TIMES);
|
|
u8 state_now = get_hall_stat(HALL_READ_TIMES);
|
|
|
float theta_now = _hall_table[state_now];
|
|
float theta_now = _hall_table[state_now];
|
|
|
u8 state_prev = _hall.state;
|
|
u8 state_prev = _hall.state;
|
|
|
|
|
+
|
|
|
|
|
+ if (!_hall.working) {
|
|
|
|
|
+ if(theta_now != 0xFFFF) {
|
|
|
|
|
+ _hall.working = true;
|
|
|
|
|
+ _hall.state = state_now;
|
|
|
|
|
+ _hall.theta = theta_now;
|
|
|
|
|
+ _hall.ticks = task_ticks_abs();
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ switch (state_now) {
|
|
|
|
|
+ case STATE_1:
|
|
|
|
|
+ if (state_prev == STATE_5) {
|
|
|
|
|
+ _hall.direction = POSITIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset + 60.0f;
|
|
|
|
|
+ }else if (state_prev == STATE_3) {
|
|
|
|
|
+ _hall.direction = NEGATIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset + 120.0f;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case STATE_2:
|
|
|
|
|
+ if (state_prev == STATE_3) {
|
|
|
|
|
+ _hall.direction = POSITIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset + 180.0f;
|
|
|
|
|
+ }else if (state_prev == STATE_6) {
|
|
|
|
|
+ _hall.direction = NEGATIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset + 240.0f;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case STATE_3:
|
|
|
|
|
+ if (state_prev == STATE_1) {
|
|
|
|
|
+ _hall.direction = POSITIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset + 120.0f;
|
|
|
|
|
+ }else if (state_prev == STATE_2) {
|
|
|
|
|
+ _hall.direction = NEGATIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset + 180.0f;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case STATE_4:
|
|
|
|
|
+ if (state_prev == STATE_6) {
|
|
|
|
|
+ _hall.direction = POSITIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset + 300.0f;
|
|
|
|
|
+ }else if (state_prev == STATE_5) {
|
|
|
|
|
+ _hall.direction = NEGATIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case STATE_5:
|
|
|
|
|
+ if (state_prev == STATE_4) {
|
|
|
|
|
+ _hall.direction = POSITIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset;
|
|
|
|
|
+ }else if (state_prev == STATE_1) {
|
|
|
|
|
+ _hall.direction = NEGATIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset + 60.0f;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case STATE_6:
|
|
|
|
|
+ if (state_prev == STATE_2) {
|
|
|
|
|
+ _hall.direction = POSITIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset + 240.0f;
|
|
|
|
|
+ }else if (state_prev == STATE_4) {
|
|
|
|
|
+ _hall.direction = NEGATIVE;
|
|
|
|
|
+ theta_now = _hall.phase_offset + 300.0f;
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ float delta_time = tick_2_s(delta_ticks(_hall.ticks));
|
|
|
|
|
+ if (delta_time == 0.0f) { //may be errors ???
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ float delta_theta = 60.0f;
|
|
|
|
|
+ _hall_put_sample(delta_theta, delta_ticks(_hall.ticks));
|
|
|
|
|
+ if (!h_samples.full) {
|
|
|
|
|
+ _hall.degree_per_s = delta_theta / delta_time;
|
|
|
|
|
+ }else {
|
|
|
|
|
+ _hall.degree_per_s = _hall_avg_speed();
|
|
|
|
|
+ }
|
|
|
|
|
+ _hall.ticks = task_ticks_abs();
|
|
|
|
|
+ _hall.theta = theta_now;
|
|
|
|
|
+ _hall.state = state_now;
|
|
|
|
|
+ _hall.e_rpm = _hall.degree_per_s / 360.0f * 60.0f;
|
|
|
|
|
+ //printf("speed :%.4f - %.4f - %.4f - %d\n", _hall.degree_per_s, delta_theta, delta_time, (int)_hall.e_rpm);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+#else
|
|
|
|
|
+void hall_sensor_handler1(void) {
|
|
|
|
|
+ u8 state_now = get_hall_stat(HALL_READ_TIMES);
|
|
|
|
|
+ float theta_now = _hall_table[state_now];
|
|
|
|
|
+ u8 state_prev = _hall.state;
|
|
|
float theta_prev = _hall.theta;
|
|
float theta_prev = _hall.theta;
|
|
|
|
|
+
|
|
|
if (!_hall.working) {
|
|
if (!_hall.working) {
|
|
|
if(theta_now != 0xFFFF) {
|
|
if(theta_now != 0xFFFF) {
|
|
|
_hall.working = true;
|
|
_hall.working = true;
|
|
@@ -164,7 +270,7 @@ void hall_sensor_handler(void) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
//printf("hall %d, %d\n", state_now, state_prev);
|
|
//printf("hall %d, %d\n", state_now, state_prev);
|
|
|
-
|
|
|
|
|
|
|
+ //{0xFFFF, 257/*1*/, 36/*2*/, 344/*3*/, 159/*4*/, 222/*5*/, 88/*6*/, 0xFFFF};
|
|
|
float delta_theta = 360.0f;
|
|
float delta_theta = 360.0f;
|
|
|
switch (state_now) {
|
|
switch (state_now) {
|
|
|
case STATE_1:
|
|
case STATE_1:
|
|
@@ -245,5 +351,5 @@ void hall_sensor_handler(void) {
|
|
|
_hall.e_rpm = _hall.degree_per_s / 360.0f * 60.0f;
|
|
_hall.e_rpm = _hall.degree_per_s / 360.0f * 60.0f;
|
|
|
//printf("speed :%.4f - %.4f - %.4f - %d\n", _hall.degree_per_s, delta_theta, delta_time, (int)_hall.e_rpm);
|
|
//printf("speed :%.4f - %.4f - %.4f - %d\n", _hall.degree_per_s, delta_theta, delta_time, (int)_hall.e_rpm);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+#endif
|
|
|
|
|
|