[STM32][TMC2660]关于TMC2660电机驱动芯片的初始化操作

  • Post author:
  • Post category:其他


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 版权协议,转载请附上原文出处链接和本声明。