356 lines
13 KiB
C
356 lines
13 KiB
C
#include "tmc5160.h"
|
||
#include "app.h"
|
||
|
||
|
||
// CS2置于 “低电平” 使能SPI
|
||
// 写的时候高位地址要加上 0x80
|
||
// 手册第5章是寄存器表,5.3.1是斜坡相关寄存器;第11章有实际单位换算表;第20章 图20.3 有运动控制流程图
|
||
// 寄存器 "RAMPMODE"->"0x20" 斜坡运动模式: 0->位置模式;1->速度模式至正VMAMX;2->速度模式至负VMAX;3->速度保持不变,最多使用2位
|
||
// 寄存器 "VSTART"->"0x23" 电机起动速度,最多使用18位,VSTART<=VSTOP
|
||
// 寄存器 "A1"->"0x24" VSTART->V1的加速度,最多使用16位
|
||
// 寄存器 "V1"->"0x25" 第一加/减速阶段速度阈值,最多使用20位;取0时禁用A1和D1,仅用AMAX和DMAX
|
||
// 寄存器 "AMAX"->"0x26" V1->VMAX的加速度,最多使用16位
|
||
// 寄存器 "DMAX"->"0x28" VMAX->V1的减速度,最多使用16位
|
||
// 寄存器 "VMAX"->"0x27" 斜坡运动目标速度,最多使用23位
|
||
// 寄存器 "D1"->"0x2A" V1->VSTOP的减速度,最多使用16位,不要在位置模式下置0
|
||
// 寄存器 "VSTOP"->"0x2B" 电机停止速度,最多使用18位,VSTART<=VSTOP,位置模式下>=10
|
||
// 一圈 200*256 微步,即每步转动 9/1280 度, 1 微步/秒 = 1.953e-5 转/秒
|
||
|
||
#define TMC5160A_CS2_L HAL_GPIO_WritePin(GPIOC,CS2_Pin,GPIO_PIN_RESET) //CS2低电平
|
||
#define TMC5160A_CS2_H HAL_GPIO_WritePin(GPIOC,CS2_Pin,GPIO_PIN_SET) //CS2高电平
|
||
|
||
#define TMC5160A_MOSI_L HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET) //MOSI低电平
|
||
#define TMC5160A_MOSI_H HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET) //MOSI高电平
|
||
|
||
#define TMC5160A_CLK_L HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET) //CLK低电平
|
||
#define TMC5160A_CLK_H HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET) //CLK高电平
|
||
|
||
#define TMC5160A_ReadVal HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14) //MISO
|
||
|
||
void TMC5160A_Init_Gpio(void)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||
/**SPI2 GPIO Configuration
|
||
PB13 ------> SPI2_SCK
|
||
PB14 ------> SPI2_MISO
|
||
PB15 ------> SPI2_MOSI
|
||
*/
|
||
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15;
|
||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||
|
||
GPIO_InitStruct.Pin = GPIO_PIN_14;
|
||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||
}
|
||
|
||
/*************常用参数配置***************/
|
||
uint32_t rampmode = 0x00000000; //斜坡运动模式 0-位置;1-速度
|
||
int xtarget = 0x00000000; //位置模式的目标位置,51200/圈
|
||
uint32_t speed_1 = 0x00004E20; //V1 过渡阶段的目标速度
|
||
uint32_t speed_max = 0x00009C40; //VMAX 目标速度
|
||
uint32_t acc_1 = 0x00000FA0; //A1 过渡阶段的加速度
|
||
uint32_t acc_max = 0x00000BB8; //AMAX 最大加速度
|
||
uint32_t dcr_1 = 0x00000FA0; //D1 过渡阶段的减速度
|
||
uint32_t dcr_max = 0x00000BB8; //DMAX 最大减速度
|
||
/*************常用参数配置***************/
|
||
|
||
void tmc5160_init(void)
|
||
{
|
||
// 纯SPI模式
|
||
TMC5160_SPIWriteInt(0x00, 0x00000004,1); // writing value 0x0000000C = 12 = 0.0 to address 0 = 0x00(GCONF) 0x00000008 不能移动 会左右抖动
|
||
// TMC5160_SPIWriteInt(0x03, 0x00000000,1); // writing value 0x00000000 = 0 = 0.0 to address 1 = 0x03(SLAVECONF)
|
||
// TMC5160_SPIWriteInt(0x05, 0x00000000,1); // writing value 0x00000000 = 0 = 0.0 to address 2 = 0x05(X_COMPARE)
|
||
// TMC5160_SPIWriteInt(0x06, 0x00000000,1); // writing value 0x00000000 = 0 = 0.0 to address 3 = 0x06(OTP_PROG)
|
||
// TMC5160_SPIWriteInt(0x08, 0x0000000E,1); // writing value 0x00000011 = 17 = 0.0 to address 4 = 0x08(FACTORY_CONF)
|
||
// TMC5160_SPIWriteInt(0x09, 0x00010606,1); // writing value 0x00010606 = 67078 = 0.0 to address 5 = 0x09(SHORT_CONF)
|
||
TMC5160_SPIWriteInt(0x0A, 0x00080400,1); // writing value 0x00080400 = 525312 = 0.0 to address 6 = 0x0A(DRV_CONF)
|
||
// TMC5160_SPIWriteInt(0x0B, 0x00000000,1); // writing value 0x00000000 = 0 = 0.0 to address 7 = 0x0B(GLOBAL_SCALER)
|
||
// 速度相关的驱动控制寄存器
|
||
TMC5160_SPIWriteInt(0x10, 0x00070A02,1); // IHOLD->0~7bit; IRUN->12~8bit
|
||
TMC5160_SPIWriteInt(0x11, 0x0000000A,1); // writing value 0x0000000A = 10 = 0.0 to address 9 = 0x11(TPOWERDOWN)
|
||
TMC5160_SPIWriteInt(0x13, 0x00000000,1); // 0x13(TPWMTHRS),StealthChop上限,超过该值后启用降噪,TSTEP >= TPWMTHRS使能降噪
|
||
TMC5160_SPIWriteInt(0x14, 0x00000000,1); // 0x14(TCOOLTHRS),降温操作,当该值 >= TSTEP >= THIGH 时,将禁用降噪,使能降温。
|
||
TMC5160_SPIWriteInt(0x15, 0x00000000,1); // 0x15(THIGH),该值大于等于TSTEP时,coolstep和steathchop都会被禁用
|
||
// 斜波发生器运动寄存器
|
||
TMC5160_SPIWriteInt(RAMPMODE_ADDR, rampmode,1); // writing value 0x00000000 = 0 = 0.0 to address 13 = 0x20(RAMPMODE)
|
||
TMC5160_SPIWriteInt(XACTUAL_ADDR, 0x00000000,1); // writing value 0xFFCC12F0 = 0 = 0.0 to address 14 = 0x21(XACTUAL)
|
||
TMC5160_SPIWriteInt(0x23, 0x00000000,1); // writing value 0x00000000 = 0 = 0.0 to address 15 = 0x23(VSTART)
|
||
TMC5160_SPIWriteInt(A1_ADDR, acc_1,1); // A1
|
||
TMC5160_SPIWriteInt(AMAX_ADDR, acc_max,1); // AMAX
|
||
TMC5160_SPIWriteInt(V1_ADDR, speed_1,1); // V1
|
||
TMC5160_SPIWriteInt(VMAX_ADDR, speed_max,1); // VMAX
|
||
TMC5160_SPIWriteInt(D1_ADDR, dcr_1,1); // D1
|
||
TMC5160_SPIWriteInt(DMAX_ADDR, dcr_max,1); // DMAX
|
||
TMC5160_SPIWriteInt(0x2B, 0x00000010,1); // VSTOP >= 0x0000000A
|
||
TMC5160_SPIWriteInt(0x2C, 0x00003FFF,1); // TZEROWAIT
|
||
TMC5160_SPIWriteInt(XTARGET_ADDR, xtarget,1); // writing value 0xFFCC12F0 = 0 = 0.0 to address 24 = 0x2D(XTARGET)
|
||
|
||
// TMC5160_SPIWriteInt(0x33, 0x00000000,1); // writing value 0x00000000 = 0 = 0.0 to address 25 = 0x33(VDCMIN)
|
||
TMC5160_SPIWriteInt(0x34, 0x00000000,1); // 0x34(SW_MODE),0x00000400使能堵转
|
||
// // 编码器寄存器
|
||
// TMC5160_SPIWriteInt(0x38, 0x00000000,1); // writing value 0x00000000 = 0 = 0.0 to address 27 = 0x38(ENCMODE)
|
||
// TMC5160_SPIWriteInt(0x39, 0x00000000,1); // writing value 0x00000000 = 0 = 0.0 to address 28 = 0x39(X_ENC)
|
||
// TMC5160_SPIWriteInt(0x3A, 0x00010000,1); // writing value 0x00010000 = 65536 = 0.0 to address 29 = 0x3A(ENC_CONST)
|
||
// TMC5160_SPIWriteInt(0x3D, 0x00000000,1); // writing value 0x00000000 = 0 = 0.0 to address 30 = 0x3D(ENC_DEVIATION)
|
||
// // 电机驱动寄存器-电机微步控制寄存器
|
||
// TMC5160_SPIWriteInt(0x60, 0xAAAAB554,1); // writing value 0xAAAAB554 = 0 = 0.0 to address 31 = 0x60(MSLUT[0])
|
||
// TMC5160_SPIWriteInt(0x61, 0x4A9554AA,1); // writing value 0x4A9554AA = 1251300522 = 0.0 to address 32 = 0x61(MSLUT[1])
|
||
// TMC5160_SPIWriteInt(0x62, 0x24492929,1); // writing value 0x24492929 = 608774441 = 0.0 to address 33 = 0x62(MSLUT[2])
|
||
// TMC5160_SPIWriteInt(0x63, 0x10104222,1); // writing value 0x10104222 = 269500962 = 0.0 to address 34 = 0x63(MSLUT[3])
|
||
// TMC5160_SPIWriteInt(0x64, 0xFBFFFFFF,1); // writing value 0xFBFFFFFF = 0 = 0.0 to address 35 = 0x64(MSLUT[4])
|
||
// TMC5160_SPIWriteInt(0x65, 0xB5BB777D,1); // writing value 0xB5BB777D = 0 = 0.0 to address 36 = 0x65(MSLUT[5])
|
||
// TMC5160_SPIWriteInt(0x66, 0x49295556,1); // writing value 0x49295556 = 1227445590 = 0.0 to address 37 = 0x66(MSLUT[6])
|
||
// TMC5160_SPIWriteInt(0x67, 0x00404222,1); // writing value 0x00404222 = 4211234 = 0.0 to address 38 = 0x67(MSLUT[7])
|
||
// TMC5160_SPIWriteInt(0x68, 0xFFFF8056,1); // writing value 0xFFFF8056 = 0 = 0.0 to address 39 = 0x68(MSLUTSEL)
|
||
// TMC5160_SPIWriteInt(0x69, 0x00F70000,1); // writing value 0x00F70000 = 16187392 = 0.0 to address 40 = 0x69(MSLUTSTART)
|
||
// // 电机驱动寄存器-驱动寄存器组
|
||
TMC5160_SPIWriteInt(0x6C, 0x000100C3,1); // 0x6C(CHOPCONF)斩波器配置
|
||
TMC5160_SPIWriteInt(0x6D, 0x00000000,1); // 0x6D(COOLCONF),16-22bit设置堵转灵敏度,值越小灵敏度越高,最大3F(63),最小C0(-64)
|
||
// TMC5160_SPIWriteInt(0x6E, 0x00000000,1); // 0x6E(DCCTRL)
|
||
TMC5160_SPIWriteInt(0x70, 0xC40C001E,1); // 0x70(PWMCONF)已开启自动调节
|
||
}
|
||
|
||
uint8_t data_r[5] = {0};//存放接收到的数据
|
||
|
||
void TMC5160_SPIWriteInt(uint8_t addr, uint32_t data, uint8_t rw)//rw = 1为写,0为读
|
||
{
|
||
|
||
char i = 0;
|
||
unsigned long dat = 0;
|
||
for(i = 0; i < 5; i++) data_r[i] = 0;
|
||
|
||
TMC5160A_CS2_L;
|
||
delay(100);
|
||
if(rw)
|
||
{
|
||
addr |= 0x80;
|
||
}
|
||
else
|
||
{
|
||
addr &= 0x7F;
|
||
}
|
||
|
||
//地址
|
||
TMC5160A_CLK_H;
|
||
for(i = 0; i < 8; i++)
|
||
{
|
||
TMC5160A_CLK_L;
|
||
if(addr & 0x80)
|
||
{
|
||
TMC5160A_MOSI_H;
|
||
}
|
||
else
|
||
{
|
||
TMC5160A_MOSI_L;
|
||
}
|
||
|
||
addr <<= 1;
|
||
TMC5160A_CLK_H;
|
||
delay(20);
|
||
|
||
data_r[0] <<= 1;
|
||
if(TMC5160A_ReadVal)
|
||
{
|
||
data_r[0] |= 1;
|
||
}
|
||
|
||
|
||
|
||
}
|
||
//数据
|
||
for(i = 0; i < 32; i++)
|
||
{
|
||
TMC5160A_CLK_L;
|
||
if(data & 0x80000000)
|
||
{
|
||
TMC5160A_MOSI_H;
|
||
}
|
||
else
|
||
{
|
||
TMC5160A_MOSI_L;
|
||
}
|
||
data <<= 1;
|
||
TMC5160A_CLK_H;
|
||
delay(20);
|
||
|
||
dat <<= 1;
|
||
if(TMC5160A_ReadVal)
|
||
{
|
||
dat |= 1;
|
||
}
|
||
|
||
}
|
||
|
||
data_r[0] = addr;
|
||
data_r[1] = dat >> 24;
|
||
data_r[2] = dat >> 16;
|
||
data_r[3] = dat >> 8;
|
||
data_r[4] = dat >> 0;
|
||
|
||
|
||
TMC5160A_CS2_H; //SPI_CS片选拉1
|
||
|
||
}
|
||
|
||
void TMC5160_SPIReadInt(uint8_t addr, uint8_t record[5])//从addr寄存器读取数据,然后记录到record中
|
||
{
|
||
char i;
|
||
for(i = 0; i < 5; i++) data_r[i] = 0;
|
||
|
||
TMC5160_SPIWriteInt(addr,0,0);
|
||
TMC5160_SPIWriteInt(addr,0,0);
|
||
memcpy(record, data_r, 5);
|
||
}
|
||
|
||
|
||
uint8_t XA[5]={0},VA[5]={0},RAMP_STAT[5],DRV_STAT[5]; //用于存放接收到的8bit*5数据
|
||
signed int XA_32 = 0,VA_32 = 0,RAMP_STAT_32 = 0,DRV_STAT_32 = 0; //用于存放从8bit*5转化得到的32位数据
|
||
char tmc5160_sw =0; //用于控制电机,在按键功能中使用
|
||
|
||
signed int Raw_32(uint8_t raw[5]) //把5*8bit数据中的0~31位拼接成1*32bit的数值并返回
|
||
{
|
||
signed int result = 0;
|
||
|
||
result |= raw[1];
|
||
result <<= 8;
|
||
result |= raw[2];
|
||
result <<= 8;
|
||
result|= raw[3];
|
||
result <<= 8;
|
||
result|= raw[4];
|
||
|
||
return result;
|
||
}
|
||
|
||
|
||
char busy_flag = 0; //忙信号标志
|
||
void tmc5160_operate(char operate_mode, uint32_t steps)
|
||
{
|
||
switch(operate_mode)
|
||
{
|
||
case 0 : //电机停止
|
||
{
|
||
TMC5160_SPIReadInt(VACTUAL_ADDR,VA); //读取实际速度VACTUAL
|
||
VA_32 = Raw_32(VA);
|
||
TMC5160_SPIReadInt(XACTUAL_ADDR,XA); //读取实际位置XACTUAL
|
||
XA_32 = Raw_32(XA);
|
||
|
||
if( VA_32 != 0) //只要实际速度不为0,就进入减速
|
||
{
|
||
busy_flag = 1;
|
||
|
||
rampmode = 0x00000000;
|
||
TMC5160_SPIWriteInt(RAMPMODE_ADDR,rampmode,1); //开启位置模式
|
||
|
||
TMC5160_SPIWriteInt(XTARGET_ADDR, XA_32, 1); //把当前位置设为目标位置,开启减速停止
|
||
}else
|
||
{
|
||
busy_flag = 0;
|
||
}
|
||
|
||
}
|
||
break;
|
||
case 1 : //电机开始正向运动
|
||
{
|
||
|
||
if( busy_flag == 0)
|
||
{
|
||
busy_flag = 1; //忙信号置1,等待到达目标位置
|
||
|
||
TMC5160_SPIReadInt(XACTUAL_ADDR,XA); //读取实际位置XACTUAL
|
||
XA_32 = Raw_32(XA);
|
||
|
||
rampmode = 0x00000000;
|
||
TMC5160_SPIWriteInt(RAMPMODE_ADDR,rampmode,1); //开启位置模式
|
||
|
||
TMC5160_SPIWriteInt(XTARGET_ADDR, XA_32 + steps, 1); //此时的实际位置+步长作为目标位置
|
||
delay(1000); //静止状态下会被 误判 成已经到达目标位置,因此进行延时等待寄存器发生变化。
|
||
}
|
||
if(busy_flag == 1)
|
||
{
|
||
TMC5160_SPIReadInt(RAMP_STAT_ADDR,RAMP_STAT); //运动过程中读取斜坡状态
|
||
RAMP_STAT_32 = Raw_32(RAMP_STAT);
|
||
|
||
if(RAMP_STAT_32 & 0x00000200) //到达目标位置,XACTUAL = XTARGET时,第9位会被置 1
|
||
{
|
||
busy_flag = 0; //忙信号清零
|
||
}
|
||
|
||
}
|
||
}
|
||
break;
|
||
case 2 : //电机开始反向运动
|
||
{
|
||
|
||
if( busy_flag == 0)
|
||
{
|
||
busy_flag = 1;
|
||
|
||
TMC5160_SPIReadInt(XACTUAL_ADDR,XA); //读取实际位置XACTUAL
|
||
XA_32 = Raw_32(XA);
|
||
|
||
rampmode = 0x00000000;
|
||
TMC5160_SPIWriteInt(RAMPMODE_ADDR,rampmode,1); //开启位置模式
|
||
|
||
TMC5160_SPIWriteInt(XTARGET_ADDR, XA_32 - steps, 1);
|
||
delay(1000); //静止状态下会被 误判 成已经到达目标位置,因此进行延时等待寄存器发生变化。
|
||
}
|
||
if(busy_flag == 1)
|
||
{
|
||
TMC5160_SPIReadInt(RAMP_STAT_ADDR,RAMP_STAT); //读取斜坡状态
|
||
RAMP_STAT_32 = Raw_32(RAMP_STAT);
|
||
|
||
if(RAMP_STAT_32 & 0x00000200) //到达目标位置,XACTUAL = XTARGET时,第9位会被置 1
|
||
{
|
||
busy_flag = 0;
|
||
}
|
||
|
||
}
|
||
}
|
||
break;
|
||
default :
|
||
{
|
||
}
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void motor_protect_ads(float threshold_neg, float threshold_pos)
|
||
{
|
||
if( (X_ads1220 <= threshold_neg) && ( motor_direc != 1 ) ) //到达负限位后停止,停止后正向
|
||
{
|
||
Motor_Run = 0;
|
||
motor_direc = 1;
|
||
}
|
||
if( (X_ads1220 >= threshold_pos) && ( motor_direc != 2 ) ) //到达正限位后停止,停止后反向
|
||
{
|
||
Motor_Run = 0;
|
||
motor_direc = 2;
|
||
}
|
||
|
||
}
|
||
|
||
void motor_protect_ocin(void)
|
||
{
|
||
if( (ocin1 == 0) && (motor_direc != 1) )
|
||
{
|
||
tmc5160_operate(0, 0);
|
||
if(busy_flag == 0) motor_direc = 1;
|
||
}
|
||
if( (ocin2 == 0) && ( motor_direc != 2 ) )
|
||
{
|
||
tmc5160_operate(0, 0);
|
||
if(busy_flag == 0) motor_direc = 2;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|