TMC2660通过SPI进行芯片参数的控制,一共需要初始化5个参数,具体参数含义可在数据手册上查到,这里不再做过多解释。
直接贴代码,根据自己的平台自行移植即可。
#define REG_DRVCTRL 0X00000000
#define REG_CHOPCONF 0X00080000
#define REG_SMARTEN 0X000A0000
#define REG_SGCSCONF 0X000C0000
#define REG_DRVCONF 0X000E0000
#define SET_BUS_MODE_DRVCONF 0x000E0000 // 设置工作在SETP/DIR模式
#define SET_SETP_DIR_MODE_DRVCTR 0x00000104 // 默认16细分,可以根据实际修改细分数 双脉冲沿模式 0x00000004->单脉冲 0x00000104->双脉冲
#define SET_SETP_DIR_MODE_DRVCTR2 0x00000000 // 默认16细分,可以根据实际修改细分数 双脉冲沿模式 0x00000004->单脉冲 0x00000104->双脉冲
#define SET_CURRENT_MODE_SGCSCONF 0x000C0000 //设置线圈电流、力矩,默认最小1/32
#define SET_COOLSTEP_MODE_SMARTEN 0x000A0000 //1/4CS
#define SET_CHOPPER_MODE_CHOPCONF 0x00080000 //设置斩波模式,可以根据实际情况更改
void motor_tmc_config( uint32_t param )
{
spi_cs_control( SPI_CS_ENABLE );
spi_readwritebyte( (uint8_t)(param>>16) );
spi_readwritebyte( (uint8_t)(param>>8) );
spi_readwritebyte( (uint8_t)param );
spi_cs_control( SPI_CS_DISABLE );
}
// 初始化配置TMC参数
void motor_tmc_param_init( void )
{
// motor_tmc_config( SET_CHOPPER_MODE_CHOPCONF|0X000812BA );
// motor_tmc_config( SET_COOLSTEP_MODE_SMARTEN|0X000A2468 );
// motor_tmc_config( SET_CHOPPER_MODE_CHOPCONF|0x000901B4 );
// motor_tmc_config( SET_COOLSTEP_MODE_SMARTEN|0X000A0202 );
// motor_tmc_config( SET_BUS_MODE_DRVCONF | 0x0050 );
// motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 );
// motor_tmc_config( SET_CURRENT_MODE_SGCSCONF|0x000C0000 );
//
// motor_curr_set( 30 );
// CHOPCONF 0x801B1 8-地址 1B(18)-正弦波偏移:B(3)快速衰减时间 1-缓慢衰减阶段的持续时间 对噪声影响大
// SMARTEN 0xA0202 A-地址 智控电流
// DRVCONF 0xEA140 E-地址 A-坡度控制:高位和低位均为10:中间值 1-短接到地检测定时器 1.2us 4-作为电流设定的采样电阻值边界:165mV重要,对噪声影响大
// DRVCTR 0x00000 0-地址 000-256细分
// SGCSCONF 0xC0000 C-地址 其余默认参数 后5位,电流,驱动能力
motor_tmc_config( SET_CHOPPER_MODE_CHOPCONF | 0x000801B1 );
motor_tmc_config( SET_COOLSTEP_MODE_SMARTEN|0X000A0202 );
motor_tmc_config( SET_BUS_MODE_DRVCONF | 0x000EA140 );
// 细分设置
//motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 );
switch( m_param.subdiv )
{
case 1:
motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 | 0x08 );
break;
case 2:
motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 | 0x07 );
break;
case 4:
motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 | 0x06 );
break;
case 8:
motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 | 0x05 );
break;
case 16:
motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 | 0x04 );
break;
case 32:
motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 | 0x03 );
break;
case 64:
motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 | 0x02 );
break;
case 128:
motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 | 0x01 );
break;
case 256:
motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 | 0x00 );
break;
default:
motor_tmc_config( SET_SETP_DIR_MODE_DRVCTR2 | 0x00 );
break;
}
motor_tmc_config( SET_CURRENT_MODE_SGCSCONF|0x000C0000 );
motor_curr_set( 80 );
}
void motor_curr_set( uint16_t power )
{
uint32_t tTorqueVal = 0; //线圈电流设置为零
tTorqueVal = (tTorqueVal|(uint32_t)((float)((float)(31*power)/(float)250)));
motor_tmc_config( SET_CURRENT_MODE_SGCSCONF | tTorqueVal );
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
* Function Name : SPI_ReadWriteByte
* Description : SPI读写一个字节(发送完成后返回本次通讯读取的数据)
* Input : uint8_t TxData 待发送的数
* Output : None
* Return : uint8_t RxData 收到的数
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
uint8_t spi_readwritebyte( uint8_t data )
{
uint32_t over_time = 10000;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
{
over_time--;
if ( over_time == 0 )
break;
// wdog_feed();
}
SPI_SendData8( SPI2, data );
over_time = 10000;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
{
over_time--;
if ( over_time == 0 )
break;
// wdog_feed();
}
return SPI_ReceiveData8(SPI2);
}
版权声明:本文为d4l6c8原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。