/** * @file tmc2240.h * @author xushenghao * @brief TMC2240驱动头文件 * @version 0.1 * @note * 1. 芯片VM需要供电,否则SPI无法正常通信 * 2. 42步进电机每步1.8度,1圈200步。1/8细分,1步=0.225度,电机转一周需要1600个脉冲 */ #ifndef __TMC2240_H #define __TMC2240_H #include "main.h" #include "spis.h" #define MOTOR_42_STEP_ANGLE 1.8f // 42步进电机每步1.8度 #define TMC2240_PWM_DUTY_DEFAULT 50 // PWM默认占空比 /* 0x00 = 0x00002108 ;; writing GCONF @ address 0=0x00 with 0x00002108=8456=0.0 0x03 = 0x00000000 ;; writing SLAVECONF @ address 1=0x03 with 0x00000000=0=0.0 0x04 = 0x4001682C ;; writing IOIN @ address 2=0x04 with 0x4001682C=1073834028=0.0 0x0A = 0x00000021 ;; writing DRV_CONF @ address 3=0x0A with 0x00000021=33=0.0 0x0B = 0x00000000 ;; writing GLOBAL_SCALER @ address 4=0x0B with 0x00000000=0=0.0 0x10 = 0x00001208 ;; writing IHOLD_IRUN @ address 5=0x10 with 0x00001208=4616=0.0 0x11 = 0x00000000 ;; writing TPOWERDOWN @ address 6=0x11 with 0x00000000=0=0.0 0x13 = 0x00000000 ;; writing TPWMTHRS @ address 7=0x13 with 0x00000000=0=0.0 0x14 = 0x000003BE ;; writing TCOOLTHRS @ address 8=0x14 with 0x000003BE=958=0.0 0x15 = 0x00000000 ;; writing THIGH @ address 9=0x15 with 0x00000000=0=0.0 0x2D = 0x00000000 ;; writing DIRECT_MODE @ address 10=0x2D with 0x00000000=0=0.0 0x38 = 0x00000000 ;; writing ENCMODE @ address 11=0x38 with 0x00000000=0=0.0 0x39 = 0x00000000 ;; writing X_ENC @ address 12=0x39 with 0x00000000=0=0.0 0x3A = 0x00010000 ;; writing ENC_CONST @ address 13=0x3A with 0x00010000=65536=0.0 0x52 = 0x0B920F25 ;; writing OTW_OV_VTH @ address 14=0x52 with 0x0B920F25=194121509=0.0 0x60 = 0xAAAAB554 ;; writing MSLUT[0] @ address 15=0x60 with 0xAAAAB554=0=0.0 0x61 = 0x4A9554AA ;; writing MSLUT[1] @ address 16=0x61 with 0x4A9554AA=1251300522=0.0 0x62 = 0x24492929 ;; writing MSLUT[2] @ address 17=0x62 with 0x24492929=608774441=0.0 0x63 = 0x10104222 ;; writing MSLUT[3] @ address 18=0x63 with 0x10104222=269500962=0.0 0x64 = 0xFBFFFFFF ;; writing MSLUT[4] @ address 19=0x64 with 0xFBFFFFFF=0=0.0 0x65 = 0xB5BB777D ;; writing MSLUT[5] @ address 20=0x65 with 0xB5BB777D=0=0.0 0x66 = 0x49295556 ;; writing MSLUT[6] @ address 21=0x66 with 0x49295556=1227445590=0.0 0x67 = 0x00404222 ;; writing MSLUT[7] @ address 22=0x67 with 0x00404222=4211234=0.0 0x68 = 0xFFFF8056 ;; writing MSLUTSEL @ address 23=0x68 with 0xFFFF8056=0=0.0 0x69 = 0x00F70000 ;; writing MSLUTSTART @ address 24=0x69 with 0x00F70000=16187392=0.0 0x6C = 0x00410153 ;; writing CHOPCONF @ address 25=0x6C with 0x00410153=4260179=0.0 0x6D = 0x00040000 ;; writing COOLCONF @ address 26=0x6D with 0x00040000=262144=0.0 0x70 = 0xC44C001E ;; writing PWMCONF @ address 27=0x70 with 0xC44C001E=0=0.0 0x74 = 0x00000000 ;; writing SG4_THRS @ address 28=0x74 with 0x00000000=0=0.0 */ #define TMC2240_GCONF 0x00 #define TMC2240_GSTAT 0x01 #define TMC2240_IFCNT 0x02 #define TMC2240_SLAVECONF 0x03 #define TMC2240_IOIN 0x04 #define TMC2240_DRV_CONF 0x0A #define TMC2240_GLOBAL_SCALER 0x0B #define TMC2240_IHOLD_IRUN 0x10 #define TMC2240_TPOWERDOWN 0x11 #define TMC2240_TSTEP 0x12 #define TMC2240_TPWMTHRS 0x13 #define TMC2240_TCOOLTHRS 0x14 #define TMC2240_THIGH 0x15 #define TMC2240_DIRECT_MODE 0x2D #define TMC2240_ENCMODE 0x38 #define TMC2240_XENC 0x39 #define TMC2240_ENC_CONST 0x3A #define TMC2240_ENC_STATUS 0x3B #define TMC2240_ENC_LATCH 0x3C #define TMC2240_ADC_VSUPPLY_AIN 0x50 #define TMC2240_ADC_TEMP 0x51 #define TMC2240_OTW_OV_VTH 0x52 #define TMC2240_MSLUT0 0x60 #define TMC2240_MSLUT1 0x61 #define TMC2240_MSLUT2 0x62 #define TMC2240_MSLUT3 0x63 #define TMC2240_MSLUT4 0x64 #define TMC2240_MSLUT5 0x65 #define TMC2240_MSLUT6 0x66 #define TMC2240_MSLUT7 0x67 #define TMC2240_MSLUTSEL 0x68 #define TMC2240_MSLUTSTART 0x69 #define TMC2240_MSCNT 0x6A #define TMC2240_MSCURACT 0x6B #define TMC2240_CHOPCONF 0x6C #define TMC2240_COOLCONF 0x6D #define TMC2240_DCCTRL 0x6E #define TMC2240_DRVSTATUS 0x6F #define TMC2240_PWMCONF 0x70 #define TMC2240_PWMSCALE 0x71 #define TMC2240_PWM_AUTO 0x72 #define TMC2240_SG4_THRS 0x74 #define TMC2240_SG4_RESULT 0x75 #define TMC2240_SG4_IND 0x76 #define TMC2240_HIGHT_BIT 0x80 typedef enum { TMC2240_1, TMC2240_MAX, } tmc2240_index_e; typedef enum { TMC2240_FORWARD, // 正转 TMC2240_BACKWARD, // 反转 } tmc2240_direction_e; typedef enum { TMC2240_MRES_256, TMC2240_MRES_128, TMC2240_MRES_64, TMC2240_MRES_32, TMC2240_MRES_16, TMC2240_MRES_8, TMC2240_MRES_4, TMC2240_MRES_2, TMC2240_MRES_1, // FULL STEP } tmc2240_mres_e; // 0x00 GCONF typedef union { uint32_t data; struct { uint32_t reserved1 : 1; /** * 停止之前的步骤执行超时检测。 * 0x0:正常时间:2^20个时钟 * 0x1:短时间:2^18个时钟 */ uint32_t fast_standstill : 1; /** * 启用StealthChop2模式。 * 0x0:无StealthChop2 * 0x1:StealthChop2电压PWM模式使能(取决于速度阈值)。从关闭状态切换 在静止状态下和在lHOLD = 时为开状态 仅限额定电流。 */ uint32_t en_pwm_mode : 1; /** * 启用StealthChop2的步进输入筛选 * 0x0:无StealthChop2 * 0x1:StealthChop2电压PWM模式使能 (取决于速度阈值)。从关闭状态切换 在静止状态下和在lHOLD=时为开状态 仅限额定电流。 */ uint32_t multistep_filt : 1; /** * 更改电机方向/方向标志 * 0x0:默认电机方向 * 0x1:电机方向相反 */ uint32_t shaft : 1; uint32_t diag0_error : 1; uint32_t diag0_otpw : 1; uint32_t diag0_stall : 1; uint32_t diag1_stall : 1; uint32_t diag1_index : 1; uint32_t diag1_onstate : 1; uint32_t reserved2 : 1; uint32_t diag0_pushpull : 1; uint32_t diag1_pushpull : 1; uint32_t small_hysteresis : 1; /** * 电机硬停止功能启用。 * 0x0:正常运行 * 0x1:紧急停止:ENCA停止定序器 当绑得很高时(不执行任何步骤 定序器、电机进入停顿状态)。 */ uint32_t stop_enable : 1; /** * 通过以下方式启用直接motpr相电流控制 * 0x0:正常运行 * 0x1:电机线圈电流和极性直接 通过串口编程:寄存器 直接模式(0x2D)指定带符号线圈A 电流(位8..0)和线圈B电流(位24..16)。在……里面 在此模式下,电流按lHOLD设置进行定标。 基于速度的StealthChop2电流调节 在此模式下不可用。自动的 StealthChop2电流调节仅适用于 步进电机速度低。 */ uint32_t direct_mode : 1; } bits; } gconf_u; // 0x01 GSTAT typedef union { uint32_t data; struct { uint32_t reset : 1; uint32_t drv_err : 1; uint32_t uv_cp : 1; uint32_t register_reset : 1; uint32_t vm_uvlo : 1; } bits; } gstat_u; // 0x0A DRVCONF typedef union { uint32_t data; struct { uint32_t current_range : 2; // 0-1 uint32_t reserved1 : 2; // 2-3 uint32_t slope_control : 2; // 4-5 } bits; } drvconf_u; // 0x0B GLOBAL_SCALER typedef union { uint32_t data; struct { uint32_t global_scale : 8; // 0-7 } bits; } global_scaler_u; // 0x10 IHOLD_IRUN typedef union { uint32_t data; struct { uint32_t ihold : 5; // 0-4 uint32_t reserved1 : 3; // 5-7 uint32_t irun : 5; // 8-12 uint32_t reserved2 : 3; // 13-15 uint32_t iholddelay : 4; // 16-19 uint32_t reserved3 : 4; // 20-23 uint32_t irundelay : 4; // 24-27 } bits; } ihold_irun_u; // 0x6C CHOPCONF typedef union { uint32_t data; struct { uint32_t toff : 4; // 0-3 uint32_t hstrt : 3; // 4-6 uint32_t hend : 4; // 7-10 uint32_t fd3 : 1; // 11 uint32_t disfdcc : 1; // 12 uint32_t reserved1 : 1; uint32_t chm : 1; // 14 uint32_t tbl : 2; // 15-16 uint32_t reserved2 : 1; uint32_t vhighfs : 1; // 18 uint32_t vhighchm : 1; // 19 uint32_t tpfd : 4; // 20-23 uint32_t mres : 4; // 24-27 uint32_t intpol : 1; // 28 uint32_t dedge : 1; // 29 uint32_t diss2g : 1; // 30 uint32_t diss2vs : 1; // 31 } bits; } chopconf_u; // 0x70 PWMCONF typedef union { uint32_t data; struct { /** * 用户定义的 PWM 幅度偏移(0-255)与静止状态下的全电机电流(CS_ACTUAL=31)相关。 (重置默认值=30) 使用 PWM_OFS 作为自动缩放的初始值, * 以加快自动调谐过程。为此,请将 PWM_OFS 设置为确定的、特定于应用的值,并将 pwm_autoscale 设置为 0。之后,将 pwm_autoscale 设置为 1。 * 完成后启用 StealthChop2。 PWM_OFS = 0 将禁用将电机电流缩放到低于电机特定的较低测量阈值。此设置应仅在某些条件下使用, * 例如当电源电压可以上下变化两倍或更多时。它可以防止电机超出调节范围,但也会防止电流降到调节限制以下。 PWM_OFS > 0 允许自动缩放到低 PWM 占空比, * 甚至低于较低的调节阈值。这允许基于实际(保持)电流比例(寄存器 IHOLD_IRUN)的低(静止)电流设置。 */ uint32_t pwm_ofs : 8; /** * PWM 幅度的速度依赖梯度: PWM_GRAD x 256 / TSTEP 此值加到 PWM_OFS 以补偿速度依赖的电机反电动势。 使用 PWM_GRAD 作为自动缩放的初始值, * 以加快自动调谐过程。为此,请将 PWM_GRAD 设置为确定的、特定于应用的值,并将 pwm_autoscale 设置为 0。之后,将 pwm_autoscale 设置为 1。 * 完成后启用 StealthChop2。 提示: 初始调谐后,可以从 PWM_GRAD_AUTO 中读取所需的初始值。 */ uint32_t pwm_grad : 8; uint32_t pwm_freq : 2; uint32_t pwm_autoscale : 1; uint32_t pwm_autograd : 1; } bits; } pwmconf_u; typedef struct { gconf_u gconf; // 0x00 GCONF gstat_u gstat; // 0x01 GSTAT drvconf_u drvconf; // 0x0A DRVCONF global_scaler_u global_scaler; // 0x0B GLOBAL_SCALER ihold_irun_u ihold_irun; // 0x10 IHOLD_IRUN chopconf_u chopconf; // 0x6C CHOPCONF pwmconf_u pwmconf; // 0x70 PWMCONF } tmc2240_config_t; typedef struct { gpio_t *en; ///< EN_PIN gpio_t *dir; ///< DIR_PIN TIM_TypeDef *timer; uint32_t time_ch; spi_t *spi; tmc2240_config_t config; tmc2240_config_t read_config; uint32_t step; __IO uint32_t step_count; // PRIVATE struct { uint32_t sysclk; // 系统时钟 uint32_t psc; // 预分频系数 uint16_t arr; // 自动重装值 auto reload value uint32_t freq; // 频率 } default_tm; struct { BOOL enable; // 使能 tmc2240_direction_e direction; // 方向 float32 percent; // 占空比 uint16_t arr; // 自动重装值(改变速度) uint32_t freq; // 频率 } params; struct { float32 step_angle; // 步进角度 uint16_t circle_pulse; // 一圈脉冲数 __IO int32_t add_pulse_count; /* 脉冲个数累计 */ __IO uint32_t pulse_count; /* 脉冲个数记录 */ __IO uint32_t step_angle_count; /* 步距个数 */ } motor; struct { uint16_t tmc2240_adc_temp; // 温度ADC值 float32 tmc2240_temperature; // 温度 } data; } tmc2240_t; void tmc2240_init(tmc2240_index_e index, SPI_TypeDef *SPIx, TIM_TypeDef *timer, uint32_t time_ch, spi_gpio_group_t *gpios); tmc2240_t *tmc2240_get(tmc2240_index_e index); void tmc2240_motor_set_angle(tmc2240_index_e index, int32_t angle); void tmc2240_motor_update(tmc2240_index_e index); void tmc2240_test(tmc2240_index_e index); void tmc2240_config_read(tmc2240_index_e index); #endif // __TMC2240_H