claude code生成5160驱动代码,等待检查

This commit is contained in:
hold the blade 2026-03-12 00:08:36 +08:00
parent 5196fff078
commit 23802adb39
2 changed files with 1146 additions and 0 deletions

835
tmc5160_driver/tmc5160.c Normal file
View File

@ -0,0 +1,835 @@
/**
* @file tmc5160.c
* @brief TMC5160
* @note SPI UART + StallGuard4
* STM32F103C8T6 + HAL (CubeMX )
*/
#include "tmc5160.h"
#include <string.h>
/* ======================== 内部宏定义 ======================== */
#define TMC5160_WRITE_BIT 0x80 /* 寄存器写标志位 */
#define TMC5160_UART_SYNC 0x05 /* UART 同步字节 */
#define TMC5160_SPI_TIMEOUT 100 /* SPI 超时 (ms) */
#define TMC5160_UART_TIMEOUT 10 /* UART 超时 (ms) */
/* ======================== SPI 片选控制 ======================== */
static inline void TMC5160_CS_Low(TMC5160_HandleTypeDef *htmc)
{
HAL_GPIO_WritePin(htmc->cs_port, htmc->cs_pin, GPIO_PIN_RESET);
}
static inline void TMC5160_CS_High(TMC5160_HandleTypeDef *htmc)
{
HAL_GPIO_WritePin(htmc->cs_port, htmc->cs_pin, GPIO_PIN_SET);
}
/* ================================================================
* UART CRC8
* TMC5160 UART 使 CRC8 0x07 0
* ================================================================ */
static uint8_t TMC5160_CalcCRC(uint8_t *data, uint8_t len)
{
uint8_t crc = 0;
for (uint8_t i = 0; i < len; i++) {
uint8_t byte = data[i];
for (uint8_t j = 0; j < 8; j++) {
if ((crc >> 7) ^ (byte >> 7)) {
crc = (crc << 1) ^ 0x07;
} else {
crc = crc << 1;
}
byte <<= 1;
}
}
return crc;
}
/* ================================================================
* SPI
* 40-bit : [(8bit)] + [(32bit)]
* : bit7=1; : bit7=0
*
* ================================================================ */
static void TMC5160_SPI_ReadWrite(TMC5160_HandleTypeDef *htmc,
uint8_t *tx, uint8_t *rx, uint8_t len)
{
TMC5160_CS_Low(htmc);
HAL_SPI_TransmitReceive(htmc->hspi, tx, rx, len, TMC5160_SPI_TIMEOUT);
TMC5160_CS_High(htmc);
}
static void TMC5160_SPI_WriteRegister(TMC5160_HandleTypeDef *htmc,
uint8_t reg, uint32_t value)
{
uint8_t tx[5], rx[5];
tx[0] = reg | TMC5160_WRITE_BIT;
tx[1] = (value >> 24) & 0xFF;
tx[2] = (value >> 16) & 0xFF;
tx[3] = (value >> 8) & 0xFF;
tx[4] = value & 0xFF;
TMC5160_SPI_ReadWrite(htmc, tx, rx, 5);
htmc->spi_status = rx[0]; /* 保存状态字节 */
}
static uint32_t TMC5160_SPI_ReadRegister(TMC5160_HandleTypeDef *htmc, uint8_t reg)
{
uint8_t tx[5] = {0}, rx[5] = {0};
/* 第一次传输:发送读请求 */
tx[0] = reg & 0x7F;
TMC5160_SPI_ReadWrite(htmc, tx, rx, 5);
/* 第二次传输:获取实际数据 */
memset(tx, 0, 5);
tx[0] = reg & 0x7F;
TMC5160_SPI_ReadWrite(htmc, tx, rx, 5);
htmc->spi_status = rx[0];
return ((uint32_t)rx[1] << 24) | ((uint32_t)rx[2] << 16) |
((uint32_t)rx[3] << 8) | (uint32_t)rx[4];
}
/* ================================================================
* UART
* : [SYNC(0x05)] [SLAVE_ADDR] [REG|0x80] [DATA x4] [CRC] 8
* : [SYNC] [SLAVE_ADDR] [REG] [CRC] 4
* : [SYNC] [0xFF] [REG] [DATA x4] [CRC] 8
* ================================================================ */
static void TMC5160_UART_WriteRegister(TMC5160_HandleTypeDef *htmc,
uint8_t reg, uint32_t value)
{
uint8_t tx[8];
tx[0] = TMC5160_UART_SYNC;
tx[1] = htmc->slave_addr;
tx[2] = reg | TMC5160_WRITE_BIT;
tx[3] = (value >> 24) & 0xFF;
tx[4] = (value >> 16) & 0xFF;
tx[5] = (value >> 8) & 0xFF;
tx[6] = value & 0xFF;
tx[7] = TMC5160_CalcCRC(tx, 7);
HAL_UART_Transmit(htmc->huart, tx, 8, TMC5160_UART_TIMEOUT);
/* 等待总线释放(单线半双工需要等回显消失) */
HAL_Delay(1);
}
static uint32_t TMC5160_UART_ReadRegister(TMC5160_HandleTypeDef *htmc, uint8_t reg)
{
uint8_t tx[4], rx[8];
/* 构造读请求帧 */
tx[0] = TMC5160_UART_SYNC;
tx[1] = htmc->slave_addr;
tx[2] = reg & 0x7F;
tx[3] = TMC5160_CalcCRC(tx, 3);
/* 发送读请求 */
HAL_UART_Transmit(htmc->huart, tx, 4, TMC5160_UART_TIMEOUT);
/* 接收响应 (8字节: sync + master_addr + reg + data[4] + crc) */
memset(rx, 0, 8);
HAL_UART_Receive(htmc->huart, rx, 8, TMC5160_UART_TIMEOUT);
/* 校验 CRC */
uint8_t crc = TMC5160_CalcCRC(rx, 7);
if (crc != rx[7]) {
return 0xFFFFFFFF; /* CRC 错误返回全1 */
}
return ((uint32_t)rx[3] << 24) | ((uint32_t)rx[4] << 16) |
((uint32_t)rx[5] << 8) | (uint32_t)rx[6];
}
/* ================================================================
*
* interface SPI UART
* ================================================================ */
void TMC5160_WriteRegister(TMC5160_HandleTypeDef *htmc, uint8_t reg, uint32_t value)
{
if (htmc->interface == TMC5160_INTERFACE_SPI) {
TMC5160_SPI_WriteRegister(htmc, reg, value);
} else {
TMC5160_UART_WriteRegister(htmc, reg, value);
}
}
uint32_t TMC5160_ReadRegister(TMC5160_HandleTypeDef *htmc, uint8_t reg)
{
if (htmc->interface == TMC5160_INTERFACE_SPI) {
return TMC5160_SPI_ReadRegister(htmc, reg);
} else {
return TMC5160_UART_ReadRegister(htmc, reg);
}
}
/* ================================================================
*
* ================================================================ */
/**
* @brief TMC5160
* @param htmc TMC5160
* @param config
* @retval HAL_OK , HAL_ERROR
*/
HAL_StatusTypeDef TMC5160_Init(TMC5160_HandleTypeDef *htmc, TMC5160_InitTypeDef *config)
{
/* 如果是 SPI 接口,先拉高片选 */
if (htmc->interface == TMC5160_INTERFACE_SPI) {
TMC5160_CS_High(htmc);
HAL_Delay(10);
}
/* 读取 IOIN 寄存器验证通信高8位包含芯片版本号TMC5160 = 0x30 */
uint32_t ioin = TMC5160_ReadRegister(htmc, TMC5160_IOIN);
uint8_t version = (ioin >> 24) & 0xFF;
if (version != 0x30) {
return HAL_ERROR; /* 芯片版本不匹配,通信可能有问题 */
}
/* 清除全局状态标志 */
TMC5160_WriteRegister(htmc, TMC5160_GSTAT, 0x07);
/* 全局电流缩放 */
if (config->global_scaler > 0) {
TMC5160_WriteRegister(htmc, TMC5160_GLOBAL_SCALER, config->global_scaler);
}
/* 设置运行/保持电流 */
TMC5160_SetIHoldIRun(htmc, config->hold_current, config->run_current, config->hold_delay);
/* 停止后降功率延迟 */
TMC5160_WriteRegister(htmc, TMC5160_TPOWERDOWN, 10);
/* 配置斩波器: TOFF + HSTRT + HEND + TBL + 细分 + 插值 */
uint32_t chopconf = 0;
chopconf |= (config->toff & 0x0F);
chopconf |= ((uint32_t)(config->hstrt & 0x07) << TMC5160_CHOPCONF_HSTRT_SHIFT);
chopconf |= ((uint32_t)(config->hend & 0x0F) << TMC5160_CHOPCONF_HEND_SHIFT);
chopconf |= ((uint32_t)(config->tbl & 0x03) << TMC5160_CHOPCONF_TBL_SHIFT);
chopconf |= ((uint32_t)config->microstep_res << TMC5160_CHOPCONF_MRES_SHIFT);
if (config->interpolation) {
chopconf |= TMC5160_CHOPCONF_INTPOL;
}
TMC5160_WriteRegister(htmc, TMC5160_CHOPCONF, chopconf);
/* 配置 GCONF: StealthChop 使能 + 方向 + 多步滤波 */
uint32_t gconf = TMC5160_GCONF_MULTISTEP_FILT;
if (config->en_pwm_mode) {
gconf |= TMC5160_GCONF_EN_PWM_MODE;
}
if (config->shaft) {
gconf |= TMC5160_GCONF_SHAFT;
}
TMC5160_WriteRegister(htmc, TMC5160_GCONF, gconf);
/* StealthChop PWM 默认配置 (自动调节) */
/* PWM_AUTOSCALE=1, PWM_AUTOGRAD=1, PWM_FREQ=01, PWM_OFS=36 */
TMC5160_WriteRegister(htmc, TMC5160_PWMCONF, 0xC40C001E);
/* 短路保护默认配置 */
TMC5160_WriteRegister(htmc, TMC5160_SHORT_CONF, 0x00010606);
TMC5160_WriteRegister(htmc, TMC5160_DRV_CONF, 0x00080400);
/* 初始化斜坡参数为安全默认值 */
TMC5160_WriteRegister(htmc, TMC5160_VSTART, 0);
TMC5160_WriteRegister(htmc, TMC5160_VSTOP, 10);
TMC5160_WriteRegister(htmc, TMC5160_AMAX, 1000);
TMC5160_WriteRegister(htmc, TMC5160_DMAX, 1000);
TMC5160_WriteRegister(htmc, TMC5160_A1, 500);
TMC5160_WriteRegister(htmc, TMC5160_D1, 500);
TMC5160_WriteRegister(htmc, TMC5160_V1, 50000);
TMC5160_WriteRegister(htmc, TMC5160_VMAX, 100000);
TMC5160_WriteRegister(htmc, TMC5160_RAMPMODE, TMC5160_MODE_POSITION);
return HAL_OK;
}
/**
* @brief TMC5160
*/
void TMC5160_DeInit(TMC5160_HandleTypeDef *htmc)
{
TMC5160_Stop(htmc);
HAL_Delay(10);
/* TOFF=0 关闭驱动桥 */
uint32_t chopconf = TMC5160_ReadRegister(htmc, TMC5160_CHOPCONF);
chopconf &= ~TMC5160_CHOPCONF_TOFF_MASK;
TMC5160_WriteRegister(htmc, TMC5160_CHOPCONF, chopconf);
}
/**
* @brief
* @retval (TMC5160 0x30)
*/
uint32_t TMC5160_GetVersion(TMC5160_HandleTypeDef *htmc)
{
uint32_t ioin = TMC5160_ReadRegister(htmc, TMC5160_IOIN);
return (ioin >> 24) & 0xFF;
}
/* ================================================================
*
* ================================================================ */
/** @brief 设置斜坡模式 */
void TMC5160_SetRampMode(TMC5160_HandleTypeDef *htmc, TMC5160_RampMode mode)
{
TMC5160_WriteRegister(htmc, TMC5160_RAMPMODE, (uint32_t)mode);
}
/**
* @brief
* @param position
*/
void TMC5160_MoveTo(TMC5160_HandleTypeDef *htmc, int32_t position)
{
TMC5160_WriteRegister(htmc, TMC5160_RAMPMODE, TMC5160_MODE_POSITION);
TMC5160_WriteRegister(htmc, TMC5160_XTARGET, (uint32_t)position);
}
/**
* @brief
* @param offset /
*/
void TMC5160_MoveBy(TMC5160_HandleTypeDef *htmc, int32_t offset)
{
int32_t current = TMC5160_GetActualPosition(htmc);
TMC5160_MoveTo(htmc, current + offset);
}
/**
* @brief
* @param velocity 0
*/
void TMC5160_Rotate(TMC5160_HandleTypeDef *htmc, int32_t velocity)
{
if (velocity >= 0) {
TMC5160_WriteRegister(htmc, TMC5160_RAMPMODE, TMC5160_MODE_VEL_POS);
TMC5160_WriteRegister(htmc, TMC5160_VMAX, (uint32_t)velocity);
} else {
TMC5160_WriteRegister(htmc, TMC5160_RAMPMODE, TMC5160_MODE_VEL_NEG);
TMC5160_WriteRegister(htmc, TMC5160_VMAX, (uint32_t)(-velocity));
}
}
/** @brief 减速停止电机 */
void TMC5160_Stop(TMC5160_HandleTypeDef *htmc)
{
TMC5160_WriteRegister(htmc, TMC5160_VMAX, 0);
TMC5160_WriteRegister(htmc, TMC5160_RAMPMODE, TMC5160_MODE_VEL_POS);
}
/** @brief 检查是否到达目标位置 (定位模式) */
uint8_t TMC5160_IsPositionReached(TMC5160_HandleTypeDef *htmc)
{
uint32_t stat = TMC5160_ReadRegister(htmc, TMC5160_RAMP_STAT);
return (stat & TMC5160_RS_POS_REACHED) ? 1 : 0;
}
/** @brief 检查是否到达目标速度 (速度模式) */
uint8_t TMC5160_IsVelocityReached(TMC5160_HandleTypeDef *htmc)
{
uint32_t stat = TMC5160_ReadRegister(htmc, TMC5160_RAMP_STAT);
return (stat & TMC5160_RS_VEL_REACHED) ? 1 : 0;
}
/* ================================================================
*
* ================================================================ */
void TMC5160_SetTargetPosition(TMC5160_HandleTypeDef *htmc, int32_t position)
{
TMC5160_WriteRegister(htmc, TMC5160_XTARGET, (uint32_t)position);
}
int32_t TMC5160_GetTargetPosition(TMC5160_HandleTypeDef *htmc)
{
return (int32_t)TMC5160_ReadRegister(htmc, TMC5160_XTARGET);
}
void TMC5160_SetActualPosition(TMC5160_HandleTypeDef *htmc, int32_t position)
{
TMC5160_WriteRegister(htmc, TMC5160_XACTUAL, (uint32_t)position);
}
int32_t TMC5160_GetActualPosition(TMC5160_HandleTypeDef *htmc)
{
return (int32_t)TMC5160_ReadRegister(htmc, TMC5160_XACTUAL);
}
int32_t TMC5160_GetActualVelocity(TMC5160_HandleTypeDef *htmc)
{
return (int32_t)TMC5160_ReadRegister(htmc, TMC5160_VACTUAL);
}
/* ================================================================
*
* : VSTART -> A1 -> V1 -> AMAX -> VMAX ()
* VMAX -> DMAX -> V1 -> D1 -> VSTOP ()
* ================================================================ */
void TMC5160_SetVMAX(TMC5160_HandleTypeDef *htmc, uint32_t vmax)
{
TMC5160_WriteRegister(htmc, TMC5160_VMAX, vmax & 0x7FFFFF);
}
void TMC5160_SetAMAX(TMC5160_HandleTypeDef *htmc, uint32_t amax)
{
TMC5160_WriteRegister(htmc, TMC5160_AMAX, amax & 0xFFFF);
}
void TMC5160_SetDMAX(TMC5160_HandleTypeDef *htmc, uint32_t dmax)
{
TMC5160_WriteRegister(htmc, TMC5160_DMAX, dmax & 0xFFFF);
}
void TMC5160_SetV1(TMC5160_HandleTypeDef *htmc, uint32_t v1)
{
TMC5160_WriteRegister(htmc, TMC5160_V1, v1 & 0xFFFFF);
}
void TMC5160_SetA1(TMC5160_HandleTypeDef *htmc, uint32_t a1)
{
TMC5160_WriteRegister(htmc, TMC5160_A1, a1 & 0xFFFF);
}
void TMC5160_SetD1(TMC5160_HandleTypeDef *htmc, uint32_t d1)
{
TMC5160_WriteRegister(htmc, TMC5160_D1, d1 & 0xFFFF);
}
void TMC5160_SetVSTART(TMC5160_HandleTypeDef *htmc, uint32_t vstart)
{
TMC5160_WriteRegister(htmc, TMC5160_VSTART, vstart & 0x3FFFF);
}
void TMC5160_SetVSTOP(TMC5160_HandleTypeDef *htmc, uint32_t vstop)
{
TMC5160_WriteRegister(htmc, TMC5160_VSTOP, vstop & 0x3FFFF);
}
void TMC5160_SetTZEROWAIT(TMC5160_HandleTypeDef *htmc, uint32_t tzerowait)
{
TMC5160_WriteRegister(htmc, TMC5160_TZEROWAIT, tzerowait & 0xFFFF);
}
/* ================================================================
*
* IHOLD_IRUN : [IHOLDDELAY(19:16)] [IRUN(12:8)] [IHOLD(4:0)]
* 0-31 = (value+1)/32 * GLOBAL_SCALER/256 * V_REF/R_SENSE
* ================================================================ */
void TMC5160_SetIHoldIRun(TMC5160_HandleTypeDef *htmc,
uint8_t ihold, uint8_t irun, uint8_t iholddelay)
{
uint32_t val = ((uint32_t)(iholddelay & 0x0F) << 16) |
((uint32_t)(irun & 0x1F) << 8) |
(uint32_t)(ihold & 0x1F);
TMC5160_WriteRegister(htmc, TMC5160_IHOLD_IRUN, val);
}
void TMC5160_SetRunCurrent(TMC5160_HandleTypeDef *htmc, uint8_t current)
{
uint32_t val = TMC5160_ReadRegister(htmc, TMC5160_IHOLD_IRUN);
val &= ~(0x1FUL << 8);
val |= ((uint32_t)(current & 0x1F) << 8);
TMC5160_WriteRegister(htmc, TMC5160_IHOLD_IRUN, val);
}
void TMC5160_SetHoldCurrent(TMC5160_HandleTypeDef *htmc, uint8_t current)
{
uint32_t val = TMC5160_ReadRegister(htmc, TMC5160_IHOLD_IRUN);
val &= ~0x1FUL;
val |= (uint32_t)(current & 0x1F);
TMC5160_WriteRegister(htmc, TMC5160_IHOLD_IRUN, val);
}
void TMC5160_SetGlobalScaler(TMC5160_HandleTypeDef *htmc, uint8_t scaler)
{
TMC5160_WriteRegister(htmc, TMC5160_GLOBAL_SCALER, scaler);
}
/* ================================================================
*
* ================================================================ */
/**
* @brief
* @param toff (3-15, 3-5, 0=)
* @param hstrt (0-7)
* @param hend (0-15, = hend - 3)
* @param tbl (0-3, 2)
*/
void TMC5160_SetChopConf(TMC5160_HandleTypeDef *htmc,
uint8_t toff, uint8_t hstrt, uint8_t hend, uint8_t tbl)
{
uint32_t val = TMC5160_ReadRegister(htmc, TMC5160_CHOPCONF);
/* 清除相关位 */
val &= ~(0x0FUL | (0x07UL << 4) | (0x0FUL << 7) | (0x03UL << 15));
/* 写入新值 */
val |= (toff & 0x0F);
val |= ((uint32_t)(hstrt & 0x07) << TMC5160_CHOPCONF_HSTRT_SHIFT);
val |= ((uint32_t)(hend & 0x0F) << TMC5160_CHOPCONF_HEND_SHIFT);
val |= ((uint32_t)(tbl & 0x03) << TMC5160_CHOPCONF_TBL_SHIFT);
TMC5160_WriteRegister(htmc, TMC5160_CHOPCONF, val);
}
/** @brief 设置细分 */
void TMC5160_SetMicrostepResolution(TMC5160_HandleTypeDef *htmc, TMC5160_MicrostepRes mres)
{
uint32_t val = TMC5160_ReadRegister(htmc, TMC5160_CHOPCONF);
val &= ~(0x0FUL << TMC5160_CHOPCONF_MRES_SHIFT);
val |= ((uint32_t)mres << TMC5160_CHOPCONF_MRES_SHIFT);
TMC5160_WriteRegister(htmc, TMC5160_CHOPCONF, val);
}
/** @brief 启用/禁用 256 细分插值 */
void TMC5160_EnableInterpolation(TMC5160_HandleTypeDef *htmc, uint8_t enable)
{
uint32_t val = TMC5160_ReadRegister(htmc, TMC5160_CHOPCONF);
if (enable) {
val |= TMC5160_CHOPCONF_INTPOL;
} else {
val &= ~TMC5160_CHOPCONF_INTPOL;
}
TMC5160_WriteRegister(htmc, TMC5160_CHOPCONF, val);
}
/* ================================================================
* StealthChop / SpreadCycle
* StealthChop: (GCONF.en_pwm_mode=1)
* SpreadCycle:
* TPWMTHRS: 使 StealthChop SpreadCycle
* ================================================================ */
void TMC5160_EnableStealthChop(TMC5160_HandleTypeDef *htmc, uint8_t enable)
{
uint32_t gconf = TMC5160_ReadRegister(htmc, TMC5160_GCONF);
if (enable) {
gconf |= TMC5160_GCONF_EN_PWM_MODE;
} else {
gconf &= ~TMC5160_GCONF_EN_PWM_MODE;
}
TMC5160_WriteRegister(htmc, TMC5160_GCONF, gconf);
}
void TMC5160_SetPWMConf(TMC5160_HandleTypeDef *htmc, uint32_t pwmconf)
{
TMC5160_WriteRegister(htmc, TMC5160_PWMCONF, pwmconf);
}
void TMC5160_SetTPWMTHRS(TMC5160_HandleTypeDef *htmc, uint32_t tpwmthrs)
{
TMC5160_WriteRegister(htmc, TMC5160_TPWMTHRS, tpwmthrs & 0xFFFFF);
}
/* ================================================================
* StallGuard4
*
* :
* SG_RESULT: 0=/,
* SGT: StallGuard (-64 ~ +63)
*
* 使:
* 1. TCOOLTHRS StallGuard
* 2. SpreadCycle 使
* 3. StealthChop TPWMTHRS
* ================================================================ */
/**
* @brief StallGuard
* @param sgt (-64 ~ +63)
* 0
*/
void TMC5160_SetStallGuardThreshold(TMC5160_HandleTypeDef *htmc, int8_t sgt)
{
uint32_t val = TMC5160_ReadRegister(htmc, TMC5160_COOLCONF);
val &= ~(0x7FUL << 16); /* 清除 SGT 位 [22:16] */
val |= ((uint32_t)(sgt & 0x7F) << 16);
TMC5160_WriteRegister(htmc, TMC5160_COOLCONF, val);
}
/**
* @brief CoolStep/StallGuard
* @note TSTEP < TCOOLTHRS StallGuard
* TSTEP TCOOLTHRS
*/
void TMC5160_SetTCOOLTHRS(TMC5160_HandleTypeDef *htmc, uint32_t tcoolthrs)
{
TMC5160_WriteRegister(htmc, TMC5160_TCOOLTHRS, tcoolthrs & 0xFFFFF);
}
/**
* @brief
* @note TSTEP < THIGH VHIGHFS 使
*/
void TMC5160_SetTHIGH(TMC5160_HandleTypeDef *htmc, uint32_t thigh)
{
TMC5160_WriteRegister(htmc, TMC5160_THIGH, thigh & 0xFFFFF);
}
/**
* @brief StallGuard
* @retval SG_RESULT (0-1023)0=
*/
uint16_t TMC5160_GetStallGuardResult(TMC5160_HandleTypeDef *htmc)
{
uint32_t status = TMC5160_ReadRegister(htmc, TMC5160_DRV_STATUS);
return (uint16_t)(status & TMC5160_DRV_SG_RESULT_MASK);
}
/**
* @brief
* @retval 1=, 0=
*/
uint8_t TMC5160_IsStalled(TMC5160_HandleTypeDef *htmc)
{
uint32_t status = TMC5160_ReadRegister(htmc, TMC5160_DRV_STATUS);
return (status & TMC5160_DRV_STALLGUARD) ? 1 : 0;
}
/**
* @brief / StallGuard
* @note RAMP_STAT.event_stop_sg
* SW_MODE sg_stop
*/
void TMC5160_EnableStallGuardStop(TMC5160_HandleTypeDef *htmc, uint8_t enable)
{
uint32_t sw_mode = TMC5160_ReadRegister(htmc, TMC5160_SW_MODE);
if (enable) {
sw_mode |= (1UL << 10); /* sg_stop 位 */
} else {
sw_mode &= ~(1UL << 10);
}
TMC5160_WriteRegister(htmc, TMC5160_SW_MODE, sw_mode);
}
/** @brief 注册堵转回调函数 */
void TMC5160_SetStallCallback(TMC5160_HandleTypeDef *htmc, TMC5160_StallCallback cb)
{
htmc->stall_callback = cb;
}
/**
* @brief StallGuard
* @note
*/
void TMC5160_StallGuardPoll(TMC5160_HandleTypeDef *htmc)
{
if (TMC5160_IsStalled(htmc)) {
if (htmc->stall_callback != NULL) {
htmc->stall_callback();
}
}
}
/* ================================================================
* CoolStep
*
* StallGuard TCOOLTHRS
* ================================================================ */
void TMC5160_SetCoolConf(TMC5160_HandleTypeDef *htmc, uint32_t coolconf)
{
TMC5160_WriteRegister(htmc, TMC5160_COOLCONF, coolconf);
}
/**
* @brief CoolStep
* @param semin CoolStep (0=, 1-15: SG_RESULT < semin*32 )
* @param semax CoolStep (0-15: SG_RESULT > (semin+semax+1)*32 )
* @param seup (0-3: 1/2/4/8)
* @param sedn (0-3: 32/8/2/1)
* @param seimin (0=IRUN/2, 1=IRUN/4)
*/
void TMC5160_ConfigCoolStep(TMC5160_HandleTypeDef *htmc,
uint8_t semin, uint8_t semax,
uint8_t seup, uint8_t sedn, uint8_t seimin)
{
uint32_t val = TMC5160_ReadRegister(htmc, TMC5160_COOLCONF);
/* 保留 SGT 位 [22:16],清除 CoolStep 位 */
val &= (0x7FUL << 16);
val |= (uint32_t)(semin & 0x0F);
val |= ((uint32_t)(seup & 0x03) << 5);
val |= ((uint32_t)(semax & 0x0F) << 8);
val |= ((uint32_t)(sedn & 0x03) << 13);
val |= ((uint32_t)(seimin & 0x01) << 15);
TMC5160_WriteRegister(htmc, TMC5160_COOLCONF, val);
}
/* ================================================================
*
* ================================================================ */
uint32_t TMC5160_GetDrvStatus(TMC5160_HandleTypeDef *htmc)
{
return TMC5160_ReadRegister(htmc, TMC5160_DRV_STATUS);
}
uint32_t TMC5160_GetRampStat(TMC5160_HandleTypeDef *htmc)
{
return TMC5160_ReadRegister(htmc, TMC5160_RAMP_STAT);
}
uint32_t TMC5160_GetGStat(TMC5160_HandleTypeDef *htmc)
{
return TMC5160_ReadRegister(htmc, TMC5160_GSTAT);
}
/** @brief 清除全局状态标志 (写1清除) */
void TMC5160_ClearGStat(TMC5160_HandleTypeDef *htmc)
{
TMC5160_WriteRegister(htmc, TMC5160_GSTAT, 0x07);
}
/** @brief 获取实际驱动电流 CS (0-31) */
uint8_t TMC5160_GetCurrentCS(TMC5160_HandleTypeDef *htmc)
{
uint32_t status = TMC5160_ReadRegister(htmc, TMC5160_DRV_STATUS);
return (uint8_t)((status & TMC5160_DRV_CS_ACTUAL_MASK) >> TMC5160_DRV_CS_ACTUAL_SHIFT);
}
/** @brief 过温关断检测 */
uint8_t TMC5160_IsOverTemp(TMC5160_HandleTypeDef *htmc)
{
return (TMC5160_ReadRegister(htmc, TMC5160_DRV_STATUS) & TMC5160_DRV_OT) ? 1 : 0;
}
/** @brief 过温预警检测 */
uint8_t TMC5160_IsOverTempWarning(TMC5160_HandleTypeDef *htmc)
{
return (TMC5160_ReadRegister(htmc, TMC5160_DRV_STATUS) & TMC5160_DRV_OTPW) ? 1 : 0;
}
/** @brief 对地短路检测 (A相或B相) */
uint8_t TMC5160_IsShortToGround(TMC5160_HandleTypeDef *htmc)
{
uint32_t s = TMC5160_ReadRegister(htmc, TMC5160_DRV_STATUS);
return (s & (TMC5160_DRV_S2GA | TMC5160_DRV_S2GB)) ? 1 : 0;
}
/** @brief 开路检测 (A相或B相) */
uint8_t TMC5160_IsOpenLoad(TMC5160_HandleTypeDef *htmc)
{
uint32_t s = TMC5160_ReadRegister(htmc, TMC5160_DRV_STATUS);
return (s & (TMC5160_DRV_OLA | TMC5160_DRV_OLB)) ? 1 : 0;
}
/** @brief 获取当前步进间隔时间 */
uint32_t TMC5160_GetTStep(TMC5160_HandleTypeDef *htmc)
{
return TMC5160_ReadRegister(htmc, TMC5160_TSTEP);
}
/* ================================================================
*
* ================================================================ */
/** @brief 设置电机旋转方向 (0=正常, 1=反转) */
void TMC5160_SetDirection(TMC5160_HandleTypeDef *htmc, uint8_t shaft)
{
uint32_t gconf = TMC5160_ReadRegister(htmc, TMC5160_GCONF);
if (shaft) {
gconf |= TMC5160_GCONF_SHAFT;
} else {
gconf &= ~TMC5160_GCONF_SHAFT;
}
TMC5160_WriteRegister(htmc, TMC5160_GCONF, gconf);
}
/* ================================================================
*
* ================================================================ */
void TMC5160_SetEncMode(TMC5160_HandleTypeDef *htmc, uint32_t encmode)
{
TMC5160_WriteRegister(htmc, TMC5160_ENCMODE, encmode);
}
int32_t TMC5160_GetEncPosition(TMC5160_HandleTypeDef *htmc)
{
return (int32_t)TMC5160_ReadRegister(htmc, TMC5160_X_ENC);
}
void TMC5160_SetEncPosition(TMC5160_HandleTypeDef *htmc, int32_t position)
{
TMC5160_WriteRegister(htmc, TMC5160_X_ENC, (uint32_t)position);
}
void TMC5160_SetEncConst(TMC5160_HandleTypeDef *htmc, uint32_t enc_const)
{
TMC5160_WriteRegister(htmc, TMC5160_ENC_CONST, enc_const);
}
/* ================================================================
*
* ================================================================ */
void TMC5160_SetSWMode(TMC5160_HandleTypeDef *htmc, uint32_t sw_mode)
{
TMC5160_WriteRegister(htmc, TMC5160_SW_MODE, sw_mode);
}
uint32_t TMC5160_GetSWMode(TMC5160_HandleTypeDef *htmc)
{
return TMC5160_ReadRegister(htmc, TMC5160_SW_MODE);
}
/* ================================================================
*
* ================================================================ */
/**
* @brief
* @param tpowerdown (0-255) 2^18
*/
void TMC5160_SetTPOWERDOWN(TMC5160_HandleTypeDef *htmc, uint8_t tpowerdown)
{
TMC5160_WriteRegister(htmc, TMC5160_TPOWERDOWN, tpowerdown);
}
/* ================================================================
* DIAG
* DIAG0/DIAG1
* MCU
* ================================================================ */
/**
* @brief DIAG0
* @param stall 1=
* @param error 1=
* @param otpw 1=
*/
void TMC5160_ConfigDiag0(TMC5160_HandleTypeDef *htmc,
uint8_t stall, uint8_t error, uint8_t otpw)
{
uint32_t gconf = TMC5160_ReadRegister(htmc, TMC5160_GCONF);
gconf &= ~(TMC5160_GCONF_DIAG0_STALL | TMC5160_GCONF_DIAG0_ERROR |
TMC5160_GCONF_DIAG0_OTPW);
if (stall) gconf |= TMC5160_GCONF_DIAG0_STALL;
if (error) gconf |= TMC5160_GCONF_DIAG0_ERROR;
if (otpw) gconf |= TMC5160_GCONF_DIAG0_OTPW;
TMC5160_WriteRegister(htmc, TMC5160_GCONF, gconf);
}
/**
* @brief DIAG1
* @param stall 1=
* @param index 1=
* @param onstate 1= chopper on
*/
void TMC5160_ConfigDiag1(TMC5160_HandleTypeDef *htmc,
uint8_t stall, uint8_t index, uint8_t onstate)
{
uint32_t gconf = TMC5160_ReadRegister(htmc, TMC5160_GCONF);
gconf &= ~(TMC5160_GCONF_DIAG1_STALL | TMC5160_GCONF_DIAG1_INDEX |
TMC5160_GCONF_DIAG1_ONSTATE);
if (stall) gconf |= TMC5160_GCONF_DIAG1_STALL;
if (index) gconf |= TMC5160_GCONF_DIAG1_INDEX;
if (onstate) gconf |= TMC5160_GCONF_DIAG1_ONSTATE;
TMC5160_WriteRegister(htmc, TMC5160_GCONF, gconf);
}

311
tmc5160_driver/tmc5160.h Normal file
View File

@ -0,0 +1,311 @@
/**
* @file tmc5160.h
* @brief TMC5160
* @note SPI UART
* StallGuard4 StealthChop/SpreadCycle
* STM32F103C8T6 + HAL
*/
#ifndef __TMC5160_H
#define __TMC5160_H
#include "stm32f1xx_hal.h"
/* ======================== 通信接口类型 ======================== */
typedef enum {
TMC5160_INTERFACE_SPI, /* SPI 接口 */
TMC5160_INTERFACE_UART /* 单线 UART 接口 */
} TMC5160_Interface;
/* ======================== 斜坡模式 ======================== */
typedef enum {
TMC5160_MODE_POSITION = 0, /* 定位模式(梯形/S形斜坡 */
TMC5160_MODE_VEL_POS = 1, /* 正向速度模式 */
TMC5160_MODE_VEL_NEG = 2, /* 反向速度模式 */
TMC5160_MODE_HOLD = 3 /* 保持模式(速度为零) */
} TMC5160_RampMode;
/* ======================== 细分设置 ======================== */
typedef enum {
TMC5160_MRES_256 = 0, /* 256 细分 */
TMC5160_MRES_128 = 1,
TMC5160_MRES_64 = 2,
TMC5160_MRES_32 = 3,
TMC5160_MRES_16 = 4,
TMC5160_MRES_8 = 5,
TMC5160_MRES_4 = 6,
TMC5160_MRES_2 = 7,
TMC5160_MRES_1 = 8 /* 整步 */
} TMC5160_MicrostepRes;
/* ======================== 寄存器地址定义 ======================== */
/* --- 通用配置寄存器 --- */
#define TMC5160_GCONF 0x00 /* 全局配置 */
#define TMC5160_GSTAT 0x01 /* 全局状态标志 */
#define TMC5160_IFCNT 0x02 /* UART 接口计数器 */
#define TMC5160_SLAVECONF 0x03 /* UART 从机配置 */
#define TMC5160_IOIN 0x04 /* IO 输入引脚状态(读) */
#define TMC5160_OUTPUT 0x04 /* IO 输出控制(写) */
#define TMC5160_X_COMPARE 0x05 /* 位置比较寄存器 */
#define TMC5160_OTP_PROG 0x06 /* OTP 编程 */
#define TMC5160_OTP_READ 0x07 /* OTP 读取 */
#define TMC5160_FACTORY_CONF 0x08 /* 工厂配置 */
#define TMC5160_SHORT_CONF 0x09 /* 短路保护配置 */
#define TMC5160_DRV_CONF 0x0A /* 驱动配置 */
#define TMC5160_GLOBAL_SCALER 0x0B /* 全局电流缩放 (0=256) */
#define TMC5160_OFFSET_READ 0x0C /* 偏移读取 */
/* --- 速度相关控制寄存器 --- */
#define TMC5160_IHOLD_IRUN 0x10 /* 保持/运行电流及延迟 */
#define TMC5160_TPOWERDOWN 0x11 /* 停止后降低电流的延迟时间 */
#define TMC5160_TSTEP 0x12 /* 实际步进间隔时间(只读) */
#define TMC5160_TPWMTHRS 0x13 /* StealthChop 速度上限阈值 */
#define TMC5160_TCOOLTHRS 0x14 /* CoolStep/StallGuard 速度下限阈值 */
#define TMC5160_THIGH 0x15 /* 高速模式切换阈值 */
/* --- 斜坡发生器寄存器 --- */
#define TMC5160_RAMPMODE 0x20 /* 斜坡模式选择 */
#define TMC5160_XACTUAL 0x21 /* 当前实际位置 */
#define TMC5160_VACTUAL 0x22 /* 当前实际速度(只读) */
#define TMC5160_VSTART 0x23 /* 起始速度 */
#define TMC5160_A1 0x24 /* 第一段加速度 */
#define TMC5160_V1 0x25 /* 第一段目标速度 */
#define TMC5160_AMAX 0x26 /* 最大加速度 */
#define TMC5160_VMAX 0x27 /* 最大速度 */
#define TMC5160_DMAX 0x28 /* 最大减速度 */
#define TMC5160_D1 0x2A /* 第一段减速度 */
#define TMC5160_VSTOP 0x2B /* 停止速度(建议 >=10 */
#define TMC5160_TZEROWAIT 0x2C /* 到达零速后等待时间 */
#define TMC5160_XTARGET 0x2D /* 目标位置 */
/* --- 斜坡状态寄存器 --- */
#define TMC5160_SW_MODE 0x34 /* 参考开关与StallGuard停止配置 */
#define TMC5160_RAMP_STAT 0x35 /* 斜坡状态标志 */
#define TMC5160_XLATCH 0x36 /* 锁存位置 */
/* --- 编码器寄存器 --- */
#define TMC5160_ENCMODE 0x38 /* 编码器模式配置 */
#define TMC5160_X_ENC 0x39 /* 编码器位置 */
#define TMC5160_ENC_CONST 0x3A /* 编码器常数 */
#define TMC5160_ENC_STATUS 0x3B /* 编码器状态 */
#define TMC5160_ENC_LATCH 0x3C /* 编码器锁存位置 */
#define TMC5160_ENC_DEVIATION 0x3D /* 编码器偏差允许值 */
/* --- 斩波器与驱动寄存器 --- */
#define TMC5160_CHOPCONF 0x6C /* 斩波器配置 */
#define TMC5160_COOLCONF 0x6D /* CoolStep 与 StallGuard 配置 */
#define TMC5160_DCCTRL 0x6E /* DC 步进控制 */
#define TMC5160_DRV_STATUS 0x6F /* 驱动状态(只读) */
#define TMC5160_PWMCONF 0x70 /* StealthChop PWM 配置 */
#define TMC5160_PWM_SCALE 0x71 /* PWM 缩放值(只读) */
#define TMC5160_PWM_AUTO 0x72 /* PWM 自动调节值(只读) */
#define TMC5160_LOST_STEPS 0x73 /* 丢步计数(只读) */
/* ======================== GCONF 位定义 ======================== */
#define TMC5160_GCONF_RECALIBRATE (1UL << 0)
#define TMC5160_GCONF_FASTSTANDSTILL (1UL << 1)
#define TMC5160_GCONF_EN_PWM_MODE (1UL << 2) /* 启用 StealthChop */
#define TMC5160_GCONF_MULTISTEP_FILT (1UL << 3)
#define TMC5160_GCONF_SHAFT (1UL << 4) /* 反转电机方向 */
#define TMC5160_GCONF_DIAG0_ERROR (1UL << 5)
#define TMC5160_GCONF_DIAG0_OTPW (1UL << 6)
#define TMC5160_GCONF_DIAG0_STALL (1UL << 7) /* DIAG0 输出堵转信号 */
#define TMC5160_GCONF_DIAG1_STALL (1UL << 8) /* DIAG1 输出堵转信号 */
#define TMC5160_GCONF_DIAG1_INDEX (1UL << 9)
#define TMC5160_GCONF_DIAG1_ONSTATE (1UL << 10)
#define TMC5160_GCONF_DIAG1_STEPS_SKIPPED (1UL << 11)
#define TMC5160_GCONF_DIAG0_PUSHPULL (1UL << 12)
#define TMC5160_GCONF_DIAG1_PUSHPULL (1UL << 13)
#define TMC5160_GCONF_SMALL_HYSTERESIS (1UL << 14)
#define TMC5160_GCONF_STOP_ENABLE (1UL << 15)
#define TMC5160_GCONF_DIRECT_MODE (1UL << 16)
#define TMC5160_GCONF_TEST_MODE (1UL << 17)
/* ======================== DRV_STATUS 位定义 ======================== */
#define TMC5160_DRV_SG_RESULT_MASK 0x3FFUL /* StallGuard 结果 [9:0] */
#define TMC5160_DRV_S2VSA (1UL << 12)
#define TMC5160_DRV_S2VSB (1UL << 13)
#define TMC5160_DRV_STEALTH (1UL << 14) /* StealthChop 活跃 */
#define TMC5160_DRV_FSACTIVE (1UL << 15) /* 全步模式活跃 */
#define TMC5160_DRV_CS_ACTUAL_MASK (0x1FUL << 16) /* 实际电流 [20:16] */
#define TMC5160_DRV_CS_ACTUAL_SHIFT 16
#define TMC5160_DRV_STALLGUARD (1UL << 24) /* StallGuard 标志 */
#define TMC5160_DRV_OT (1UL << 25) /* 过温关断 */
#define TMC5160_DRV_OTPW (1UL << 26) /* 过温预警 */
#define TMC5160_DRV_S2GA (1UL << 27) /* A相对地短路 */
#define TMC5160_DRV_S2GB (1UL << 28) /* B相对地短路 */
#define TMC5160_DRV_OLA (1UL << 29) /* A相开路 */
#define TMC5160_DRV_OLB (1UL << 30) /* B相开路 */
#define TMC5160_DRV_STST (1UL << 31) /* 电机静止 */
/* ======================== RAMP_STAT 位定义 ======================== */
#define TMC5160_RS_STOP_L (1UL << 0) /* 左限位开关触发 */
#define TMC5160_RS_STOP_R (1UL << 1) /* 右限位开关触发 */
#define TMC5160_RS_LATCH_L (1UL << 2)
#define TMC5160_RS_LATCH_R (1UL << 3)
#define TMC5160_RS_EV_STOP_L (1UL << 4) /* 左限位停止事件 */
#define TMC5160_RS_EV_STOP_R (1UL << 5) /* 右限位停止事件 */
#define TMC5160_RS_EV_STOP_SG (1UL << 6) /* StallGuard 停止事件 */
#define TMC5160_RS_EV_POS_REACHED (1UL << 7) /* 到达目标位置事件 */
#define TMC5160_RS_VEL_REACHED (1UL << 8) /* 到达目标速度 */
#define TMC5160_RS_POS_REACHED (1UL << 9) /* 位置已到达 */
#define TMC5160_RS_VZERO (1UL << 10) /* 速度为零 */
#define TMC5160_RS_ZEROWAIT (1UL << 11) /* 零速等待中 */
#define TMC5160_RS_SECOND_MOVE (1UL << 12) /* 第二次运动 */
#define TMC5160_RS_SG (1UL << 13) /* StallGuard 实时状态 */
/* ======================== CHOPCONF 位偏移 ======================== */
#define TMC5160_CHOPCONF_TOFF_MASK 0x0FUL
#define TMC5160_CHOPCONF_HSTRT_SHIFT 4
#define TMC5160_CHOPCONF_HEND_SHIFT 7
#define TMC5160_CHOPCONF_TBL_SHIFT 15
#define TMC5160_CHOPCONF_VHIGHFS (1UL << 18)
#define TMC5160_CHOPCONF_VHIGHCHM (1UL << 19)
#define TMC5160_CHOPCONF_MRES_SHIFT 24
#define TMC5160_CHOPCONF_INTPOL (1UL << 28) /* 256细分插值 */
#define TMC5160_CHOPCONF_DEDGE (1UL << 29)
#define TMC5160_CHOPCONF_DISS2G (1UL << 30)
#define TMC5160_CHOPCONF_DISS2VS (1UL << 31)
/* ======================== StallGuard 回调函数类型 ======================== */
typedef void (*TMC5160_StallCallback)(void);
/* ======================== TMC5160 句柄结构体 ======================== */
typedef struct {
TMC5160_Interface interface; /* 通信接口类型 */
/* SPI 接口相关 */
SPI_HandleTypeDef *hspi; /* SPI 句柄指针 */
GPIO_TypeDef *cs_port; /* 片选 GPIO 端口 */
uint16_t cs_pin; /* 片选 GPIO 引脚 */
/* UART 接口相关 */
UART_HandleTypeDef *huart; /* UART 句柄指针 */
uint8_t slave_addr; /* UART 从机地址 (0-3) */
/* 运行状态 */
uint8_t spi_status; /* 最近一次 SPI 状态字节 */
/* StallGuard 回调 */
TMC5160_StallCallback stall_callback;
} TMC5160_HandleTypeDef;
/* ======================== 初始化配置结构体 ======================== */
typedef struct {
uint8_t run_current; /* 运行电流 0-31 (IRUN) */
uint8_t hold_current; /* 保持电流 0-31 (IHOLD) */
uint8_t hold_delay; /* 保持延迟 0-15 (IHOLDDELAY) */
uint8_t global_scaler; /* 全局电流缩放 0-255, 0表示256 */
TMC5160_MicrostepRes microstep_res; /* 细分设置 */
uint8_t en_pwm_mode; /* 1=StealthChop, 0=SpreadCycle */
uint8_t shaft; /* 电机方向 0/1 */
uint8_t interpolation; /* 256细分插值 0/1 */
uint8_t toff; /* 斩波器关断时间 (3-15, 推荐3-5) */
uint8_t tbl; /* 比较器空白时间 (0-3, 推荐2) */
uint8_t hstrt; /* 迟滞起始值 (0-7) */
uint8_t hend; /* 迟滞结束值 (0-15, 实际值 -3~12) */
} TMC5160_InitTypeDef;
/* ======================== 函数声明 ======================== */
/* ---------- 底层寄存器读写 ---------- */
void TMC5160_WriteRegister(TMC5160_HandleTypeDef *htmc, uint8_t reg, uint32_t value);
uint32_t TMC5160_ReadRegister(TMC5160_HandleTypeDef *htmc, uint8_t reg);
/* ---------- 初始化与复位 ---------- */
HAL_StatusTypeDef TMC5160_Init(TMC5160_HandleTypeDef *htmc, TMC5160_InitTypeDef *config);
void TMC5160_DeInit(TMC5160_HandleTypeDef *htmc);
uint32_t TMC5160_GetVersion(TMC5160_HandleTypeDef *htmc);
/* ---------- 运动控制 ---------- */
void TMC5160_SetRampMode(TMC5160_HandleTypeDef *htmc, TMC5160_RampMode mode);
void TMC5160_MoveTo(TMC5160_HandleTypeDef *htmc, int32_t position);
void TMC5160_MoveBy(TMC5160_HandleTypeDef *htmc, int32_t offset);
void TMC5160_Rotate(TMC5160_HandleTypeDef *htmc, int32_t velocity);
void TMC5160_Stop(TMC5160_HandleTypeDef *htmc);
uint8_t TMC5160_IsPositionReached(TMC5160_HandleTypeDef *htmc);
uint8_t TMC5160_IsVelocityReached(TMC5160_HandleTypeDef *htmc);
/* ---------- 位置与速度读写 ---------- */
void TMC5160_SetTargetPosition(TMC5160_HandleTypeDef *htmc, int32_t position);
int32_t TMC5160_GetTargetPosition(TMC5160_HandleTypeDef *htmc);
void TMC5160_SetActualPosition(TMC5160_HandleTypeDef *htmc, int32_t position);
int32_t TMC5160_GetActualPosition(TMC5160_HandleTypeDef *htmc);
int32_t TMC5160_GetActualVelocity(TMC5160_HandleTypeDef *htmc);
/* ---------- 斜坡参数设置 ---------- */
void TMC5160_SetVMAX(TMC5160_HandleTypeDef *htmc, uint32_t vmax);
void TMC5160_SetAMAX(TMC5160_HandleTypeDef *htmc, uint32_t amax);
void TMC5160_SetDMAX(TMC5160_HandleTypeDef *htmc, uint32_t dmax);
void TMC5160_SetV1(TMC5160_HandleTypeDef *htmc, uint32_t v1);
void TMC5160_SetA1(TMC5160_HandleTypeDef *htmc, uint32_t a1);
void TMC5160_SetD1(TMC5160_HandleTypeDef *htmc, uint32_t d1);
void TMC5160_SetVSTART(TMC5160_HandleTypeDef *htmc, uint32_t vstart);
void TMC5160_SetVSTOP(TMC5160_HandleTypeDef *htmc, uint32_t vstop);
void TMC5160_SetTZEROWAIT(TMC5160_HandleTypeDef *htmc, uint32_t tzerowait);
/* ---------- 电流控制 ---------- */
void TMC5160_SetRunCurrent(TMC5160_HandleTypeDef *htmc, uint8_t current);
void TMC5160_SetHoldCurrent(TMC5160_HandleTypeDef *htmc, uint8_t current);
void TMC5160_SetIHoldIRun(TMC5160_HandleTypeDef *htmc, uint8_t ihold, uint8_t irun, uint8_t iholddelay);
void TMC5160_SetGlobalScaler(TMC5160_HandleTypeDef *htmc, uint8_t scaler);
/* ---------- 斩波器配置 ---------- */
void TMC5160_SetChopConf(TMC5160_HandleTypeDef *htmc, uint8_t toff, uint8_t hstrt, uint8_t hend, uint8_t tbl);
void TMC5160_SetMicrostepResolution(TMC5160_HandleTypeDef *htmc, TMC5160_MicrostepRes mres);
void TMC5160_EnableInterpolation(TMC5160_HandleTypeDef *htmc, uint8_t enable);
/* ---------- StealthChop / SpreadCycle ---------- */
void TMC5160_EnableStealthChop(TMC5160_HandleTypeDef *htmc, uint8_t enable);
void TMC5160_SetPWMConf(TMC5160_HandleTypeDef *htmc, uint32_t pwmconf);
void TMC5160_SetTPWMTHRS(TMC5160_HandleTypeDef *htmc, uint32_t tpwmthrs);
/* ---------- StallGuard4 堵转检测 ---------- */
void TMC5160_SetStallGuardThreshold(TMC5160_HandleTypeDef *htmc, int8_t sgt);
void TMC5160_SetTCOOLTHRS(TMC5160_HandleTypeDef *htmc, uint32_t tcoolthrs);
void TMC5160_SetTHIGH(TMC5160_HandleTypeDef *htmc, uint32_t thigh);
uint16_t TMC5160_GetStallGuardResult(TMC5160_HandleTypeDef *htmc);
uint8_t TMC5160_IsStalled(TMC5160_HandleTypeDef *htmc);
void TMC5160_EnableStallGuardStop(TMC5160_HandleTypeDef *htmc, uint8_t enable);
void TMC5160_SetStallCallback(TMC5160_HandleTypeDef *htmc, TMC5160_StallCallback cb);
void TMC5160_StallGuardPoll(TMC5160_HandleTypeDef *htmc);
/* ---------- CoolStep 自适应电流 ---------- */
void TMC5160_SetCoolConf(TMC5160_HandleTypeDef *htmc, uint32_t coolconf);
void TMC5160_ConfigCoolStep(TMC5160_HandleTypeDef *htmc,
uint8_t semin, uint8_t semax, uint8_t seup, uint8_t sedn, uint8_t seimin);
/* ---------- 状态查询 ---------- */
uint32_t TMC5160_GetDrvStatus(TMC5160_HandleTypeDef *htmc);
uint32_t TMC5160_GetRampStat(TMC5160_HandleTypeDef *htmc);
uint32_t TMC5160_GetGStat(TMC5160_HandleTypeDef *htmc);
void TMC5160_ClearGStat(TMC5160_HandleTypeDef *htmc);
uint8_t TMC5160_GetCurrentCS(TMC5160_HandleTypeDef *htmc);
uint8_t TMC5160_IsOverTemp(TMC5160_HandleTypeDef *htmc);
uint8_t TMC5160_IsOverTempWarning(TMC5160_HandleTypeDef *htmc);
uint8_t TMC5160_IsShortToGround(TMC5160_HandleTypeDef *htmc);
uint8_t TMC5160_IsOpenLoad(TMC5160_HandleTypeDef *htmc);
uint32_t TMC5160_GetTStep(TMC5160_HandleTypeDef *htmc);
/* ---------- 电机方向 ---------- */
void TMC5160_SetDirection(TMC5160_HandleTypeDef *htmc, uint8_t shaft);
/* ---------- 编码器 ---------- */
void TMC5160_SetEncMode(TMC5160_HandleTypeDef *htmc, uint32_t encmode);
int32_t TMC5160_GetEncPosition(TMC5160_HandleTypeDef *htmc);
void TMC5160_SetEncPosition(TMC5160_HandleTypeDef *htmc, int32_t position);
void TMC5160_SetEncConst(TMC5160_HandleTypeDef *htmc, uint32_t enc_const);
/* ---------- 限位开关配置 ---------- */
void TMC5160_SetSWMode(TMC5160_HandleTypeDef *htmc, uint32_t sw_mode);
uint32_t TMC5160_GetSWMode(TMC5160_HandleTypeDef *htmc);
/* ---------- 功率管理 ---------- */
void TMC5160_SetTPOWERDOWN(TMC5160_HandleTypeDef *htmc, uint8_t tpowerdown);
/* ---------- DIAG 引脚配置 ---------- */
void TMC5160_ConfigDiag0(TMC5160_HandleTypeDef *htmc, uint8_t stall, uint8_t error, uint8_t otpw);
void TMC5160_ConfigDiag1(TMC5160_HandleTypeDef *htmc, uint8_t stall, uint8_t index, uint8_t onstate);
#endif /* __TMC5160_H */