2024-04-30 09:57:59 +08:00
|
|
|
#include "by_stepper.h"
|
|
|
|
|
|
2024-05-01 01:51:36 +08:00
|
|
|
#include <math.h>
|
2024-04-30 09:57:59 +08:00
|
|
|
#include <string.h>
|
|
|
|
|
#include <dwt_delay.h>
|
|
|
|
|
#include "by_debug.h"
|
|
|
|
|
|
2024-05-01 01:51:36 +08:00
|
|
|
#define GEAR_INDEXING_DIAMETER (16.0f) // 齿轮分度圆直径
|
|
|
|
|
#define GEAR_MODULUS (2.0f) // 齿轮模数
|
|
|
|
|
#define ENCODER_PULSE_PER_CIRCLE (2048.0f) // 编码器每圈脉冲数
|
|
|
|
|
#define MILLIMETER_PER_CIRCLE (GEAR_INDEXING_DIAMETER * GEAR_MODULUS) // 齿轮每圈行走长度
|
|
|
|
|
#define ENCODER_PULSE_PER_MILLIMETER (ENCODER_PULSE_PER_CIRCLE / MILLIMETER_PER_CIRCLE) // 编码器每毫米脉冲数
|
|
|
|
|
#define STEPPER_STEP_ANGLE (1.8f) // 步进角度
|
|
|
|
|
#define DRIVER_PULSE_PER_STEP (16.0f) // 驱动器细分
|
|
|
|
|
#define DRIVER_PULSE_PER_CIRCLE (360.0f / STEPPER_STEP_ANGLE * DRIVER_PULSE_PER_STEP) // 驱动器每圈脉冲数
|
|
|
|
|
#define DRIVER_PULSE_PER_MILLIMETER (DRIVER_PULSE_PER_CIRCLE / MILLIMETER_PER_CIRCLE) // 驱动器每毫米脉冲数
|
|
|
|
|
|
|
|
|
|
#define ENCODER_ERROR_THRESHOLD (20)
|
|
|
|
|
|
|
|
|
|
int64_t position = 0;
|
|
|
|
|
int64_t position_aim = 0;
|
|
|
|
|
int64_t position_offset = 0;
|
|
|
|
|
|
|
|
|
|
uint8_t running_flag = 0;
|
2024-05-01 12:16:55 +08:00
|
|
|
uint8_t reset_flag = 0;
|
2024-05-01 01:51:36 +08:00
|
|
|
|
2024-04-30 09:57:59 +08:00
|
|
|
// TODO 是否增加一个动作列表?一般都比较简单吧
|
|
|
|
|
|
|
|
|
|
struct by_stepper_t {
|
2024-05-01 01:51:36 +08:00
|
|
|
uint8_t dir;
|
|
|
|
|
stepper_speed_t speed;
|
2024-04-30 09:57:59 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct by_stepper_t by_stepper;
|
|
|
|
|
|
2024-05-01 01:51:36 +08:00
|
|
|
static int64_t abs_s64(int64_t x)
|
2024-04-30 09:57:59 +08:00
|
|
|
{
|
2024-05-01 01:51:36 +08:00
|
|
|
return x > 0 ? x : -x;
|
2024-04-30 09:57:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void by_stepper_set_dir(uint8_t dir)
|
|
|
|
|
{
|
2024-05-01 01:51:36 +08:00
|
|
|
by_stepper.dir = dir;
|
2024-04-30 09:57:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void by_stepper_set_speed(stepper_speed_t speed)
|
|
|
|
|
{
|
2024-05-01 01:51:36 +08:00
|
|
|
by_stepper.speed = speed;
|
2024-04-30 09:57:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void by_stepper_run(void)
|
|
|
|
|
{
|
2024-05-01 01:51:36 +08:00
|
|
|
// 根据预设条件发送脉冲
|
2024-05-01 12:16:55 +08:00
|
|
|
gpio_bits_write(GPIOA, GPIO_PINS_9, FALSE); // EN
|
|
|
|
|
|
2024-05-01 01:51:36 +08:00
|
|
|
gpio_bits_write(GPIOA, GPIO_PINS_8, by_stepper.dir ? TRUE : FALSE); // DIR
|
|
|
|
|
gpio_bits_write(GPIOB, GPIO_PINS_15, !gpio_output_data_bit_read(GPIOB, GPIO_PINS_15)); // CLK
|
|
|
|
|
DWT_Delay(40U * (uint16_t)by_stepper.speed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void by_stepper_stop(uint8_t hold)
|
|
|
|
|
{
|
|
|
|
|
gpio_bits_write(GPIOA, GPIO_PINS_9, hold ? FALSE : TRUE); // EN
|
|
|
|
|
|
|
|
|
|
gpio_bits_write(GPIOA, GPIO_PINS_8, FALSE); // DIR
|
|
|
|
|
gpio_bits_write(GPIOB, GPIO_PINS_15, FALSE); // CLK
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void by_stepper_set_position_millimeter(float distance)
|
|
|
|
|
{
|
|
|
|
|
if (!running_flag) {
|
2024-05-01 12:16:55 +08:00
|
|
|
// 设置距离较小时直接复位,减少累计定位误差
|
|
|
|
|
if (distance < 3 && distance > -3) {
|
|
|
|
|
reset_flag = 1;
|
|
|
|
|
running_flag = 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gpio_bits_write(GPIOA, GPIO_PINS_9, FALSE); // EN
|
2024-05-01 01:51:36 +08:00
|
|
|
position_aim = (int64_t)(distance * ENCODER_PULSE_PER_MILLIMETER);
|
|
|
|
|
position_offset = position_aim - position;
|
|
|
|
|
running_flag = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void by_stepper_add_position_millimeter(float distance)
|
|
|
|
|
{
|
|
|
|
|
if (!running_flag) {
|
2024-05-01 12:16:55 +08:00
|
|
|
gpio_bits_write(GPIOA, GPIO_PINS_9, FALSE); // EN
|
2024-05-01 01:51:36 +08:00
|
|
|
position_aim = position + (int64_t)(distance * ENCODER_PULSE_PER_MILLIMETER);
|
|
|
|
|
position_offset = position_aim - position;
|
|
|
|
|
running_flag = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void by_stepper_init(void)
|
|
|
|
|
{
|
|
|
|
|
uint32_t slow_start_cnt = 30000;
|
|
|
|
|
LOGD("by_stepper init...");
|
|
|
|
|
|
|
|
|
|
memset(&by_stepper, 0x00, sizeof(by_stepper));
|
|
|
|
|
|
|
|
|
|
gpio_bits_write(GPIOB, GPIO_PINS_12, TRUE); // MODE2
|
|
|
|
|
gpio_bits_write(GPIOB, GPIO_PINS_13, FALSE); // MODE1
|
|
|
|
|
gpio_bits_write(GPIOB, GPIO_PINS_14, FALSE); // MODE0
|
|
|
|
|
gpio_bits_write(GPIOA, GPIO_PINS_9, FALSE); // EN
|
|
|
|
|
gpio_bits_write(GPIOA, GPIO_PINS_8, TRUE); // DIR
|
|
|
|
|
gpio_bits_write(GPIOB, GPIO_PINS_15, FALSE); // CLK
|
|
|
|
|
|
|
|
|
|
by_stepper_set_dir(0);
|
2024-06-10 17:42:53 +08:00
|
|
|
// by_stepper_set_speed(STEPPER_SPEED_DIV2);
|
2024-05-01 01:51:36 +08:00
|
|
|
|
2024-06-10 17:42:53 +08:00
|
|
|
// while (gpio_input_data_bit_read(GPIOB, GPIO_PINS_10) == SET && slow_start_cnt--) {
|
|
|
|
|
// gpio_bits_write(GPIOA, GPIO_PINS_8, by_stepper.dir ? TRUE : FALSE); // DIR
|
|
|
|
|
// gpio_bits_write(GPIOB, GPIO_PINS_15, !gpio_output_data_bit_read(GPIOB, GPIO_PINS_15)); // CLK
|
|
|
|
|
// DWT_Delay(40U * (uint16_t)by_stepper.speed);
|
|
|
|
|
// }
|
2024-05-01 01:51:36 +08:00
|
|
|
|
|
|
|
|
by_stepper_set_speed(STEPPER_SPEED_DIV1);
|
|
|
|
|
|
|
|
|
|
while (gpio_input_data_bit_read(GPIOB, GPIO_PINS_10) == SET) {
|
2024-04-30 09:57:59 +08:00
|
|
|
gpio_bits_write(GPIOA, GPIO_PINS_8, by_stepper.dir ? TRUE : FALSE); // DIR
|
|
|
|
|
gpio_bits_write(GPIOB, GPIO_PINS_15, !gpio_output_data_bit_read(GPIOB, GPIO_PINS_15)); // CLK
|
|
|
|
|
DWT_Delay(40U * (uint16_t)by_stepper.speed);
|
2024-05-01 01:51:36 +08:00
|
|
|
}
|
|
|
|
|
|
2024-05-01 12:16:55 +08:00
|
|
|
position = 0; // 位置归零
|
|
|
|
|
position_aim = 0;
|
|
|
|
|
position_offset = 0;
|
2024-05-01 01:51:36 +08:00
|
|
|
tmr_counter_value_set(TMR3, 0);
|
|
|
|
|
|
|
|
|
|
LOGD("by_stepper init ok");
|
2024-06-10 17:42:53 +08:00
|
|
|
|
|
|
|
|
by_stepper_set_dir(1);
|
|
|
|
|
by_stepper_set_position_millimeter(-160.0f);
|
2024-05-01 01:51:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void by_stepper_loop(void)
|
|
|
|
|
{
|
|
|
|
|
int16_t temp = (int16_t)tmr_counter_value_get(TMR3);
|
|
|
|
|
position += (int64_t)temp;
|
|
|
|
|
tmr_counter_value_set(TMR3, 0);
|
|
|
|
|
|
|
|
|
|
if (running_flag) {
|
|
|
|
|
|
2024-05-01 12:16:55 +08:00
|
|
|
if (reset_flag) // 复位模式
|
|
|
|
|
{
|
|
|
|
|
by_stepper_init();
|
|
|
|
|
running_flag = 0;
|
|
|
|
|
reset_flag = 0;
|
|
|
|
|
} else // 正常模式
|
|
|
|
|
{
|
|
|
|
|
if (position_offset > 0) {
|
|
|
|
|
by_stepper_set_dir(0);
|
|
|
|
|
by_stepper_run();
|
|
|
|
|
} else if (position_offset < 0) {
|
|
|
|
|
by_stepper_set_dir(1);
|
|
|
|
|
by_stepper_run();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 当定位误差小于阈值时,停止运动。否则重新计算定位误差
|
|
|
|
|
if (abs_s64(position_aim - position) < ENCODER_ERROR_THRESHOLD) {
|
|
|
|
|
running_flag = 0;
|
|
|
|
|
position_offset = 0;
|
|
|
|
|
} else {
|
|
|
|
|
position_offset = position_aim - position;
|
|
|
|
|
}
|
2024-05-01 01:51:36 +08:00
|
|
|
}
|
2024-05-01 12:16:55 +08:00
|
|
|
|
2024-05-01 01:51:36 +08:00
|
|
|
} else {
|
2024-06-10 17:42:53 +08:00
|
|
|
by_stepper_stop(1);
|
2024-05-01 01:51:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if (position_offset) {
|
|
|
|
|
// if (position_offset > 0) {
|
|
|
|
|
// by_stepper_set_dir(0);
|
|
|
|
|
// by_stepper_run();
|
|
|
|
|
// position_offset -= 1;
|
|
|
|
|
// } else if (position_offset++ < 0) {
|
|
|
|
|
// by_stepper_set_dir(1);
|
|
|
|
|
// by_stepper_run();
|
|
|
|
|
// position_offset += 1;
|
|
|
|
|
// }
|
|
|
|
|
// } else {
|
|
|
|
|
// by_stepper_stop(0);
|
|
|
|
|
// }
|
2024-04-30 09:57:59 +08:00
|
|
|
}
|
|
|
|
|
|
2024-05-01 01:51:36 +08:00
|
|
|
void by_stpepper_int(void)
|
2024-04-30 09:57:59 +08:00
|
|
|
{
|
2024-05-01 01:51:36 +08:00
|
|
|
// position += (int16_t)(tmr_counter_value_get(TMR3));
|
|
|
|
|
// tmr_counter_value_set(TMR3, 0);
|
2024-04-30 09:57:59 +08:00
|
|
|
}
|