0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于TMC2660驱动芯片的步进电机驱动设计

CHANBAEK 来源:木南创智 作者:尹家军 2022-12-14 16:17 次阅读

步进电机的应用非常广泛,在各种设备中经常会遇到,而步进电机的驱动则是使用步进电机必不可少的部分,可以有多种方式来实现步进电机的驱动,在这里我们来考虑一下基于TMC2660驱动芯片的步进电机驱动。

1 、功能概述

TMC2660是德国TRINAMIC公司产的步进电机驱动芯片。TMC2660驱动器提供了业界领先的功能集,包括高分辨率微步、无传感器机械负载测量、负载自适应功率优化和低共振斩波操作。拥有标准SPI和STEP/DIR两种接口模式。集成功率MOSFET处理电机电流高达2.2A。集成的保护和诊断功能支持稳健和可靠的运行。其结构图如下:

Dingtalk_20221206154648.jpg

TMC2660的参数配置通过SPI接口来实现。TMC2660具有5个配置和控制寄存器,通过SPI端口来访问这些寄存器。这些寄存器的结构定义如下所示:

Dingtalk_20221206154648.jpg

所有的寄存器都是20位,在最高的2位或3位表示的是寄存器地址也称为操作码。根据具体的寄存器我们选择不同的操作码实现对寄存器的写操作。每一个写操作都会有一个20位的数据返回。而返回数据的内容可以通过修改配置寄存器来定义。具体的格式如下图所示:

Dingtalk_20221206154648.jpg

2 、驱动设计于实现

我们已经了解了TMC2660步进电机驱动芯片的基本技术参数,接下来我们就需要据此来实现TMC2660步进电机驱动芯片的驱动程序的设计与实现。

2.1 、对象定义

我们依然是居于对象来实现相关的操作。所以我们首先要定义对象,出于适用性考虑,我们要定义对象的类型并将具体的对象实例化,接下来我们就来抽象对象类型和实例化对象的操作。

2.1.1 、对象的抽象

对于一个对象最主要包括属性与操作两方面内容,所以我们先来考虑TMC2660对象具有哪些属性和操作,并抽象出较为通用的TMC2660对象类型。

对于步进电机的驱动都具有哪些属性呢?我们考虑到一台步进电机至少具备启停控制命令、方向控制命令、速度设定以及运行状态等,这些对于每一台步进电机来说,在不同的设置下代表不同的状态,所以我们将其作为其属性来处理。此外,与具体的电机相关的参数如固有步距角、微步设置及当前脉冲频率等。以及与TMC2660相关的状态、寄存器的值、速度规划等都与具体的应用需求相关、用以记录其运行和配置状态,所以我们将其作为属性。

然后再来看一看TMC2660对象需要实现的操作。对于TMC2660对象来说,我们要操作它,需要向其发送和读取数据,需要操作片选信号和使能信号,而这些行为依赖于具体的操作平台,所以我们将其作为对象的操作来设定。TMC2660可以工作在SPI模式或者SD模式,而在SD模式时,存在脉冲和方向的控制,这同样依赖于具体的软硬件操作平台,所以我们也将其作为对象的操作来实现。更具以上的分析我们可以抽象出TMC2660对象类型如下:

/*定义TMC2660对象类型*/
typedef struct TMC2660Object {
    float microStep;//微步设置
    float stepAngle;//固有步进角
    float frequency;    //运行频率
    uint16_t *pStartStop;   //启停操作命令
    uint16_t *pDirection;   //方向控制
    uint16_t *pRotateSet;   //转速设定
    uint16_t *pMotorState;  //电机状态
   
    uint32_t status;        //TMC通讯返回状态
    uint32_t Register[5];    //寄存器
    void (*WriteRead)(uint8_t*wData,uint16_t wSize,uint8_t *rData,uint16_t rSize);
    void(*ChipSelcet)(TMC2660CSType cs);   //片选信号
    void(*StartStop)(TMC2660SSType ss);    //启停操作函数
    void(*Direct)(TMC2660DIRType dir);     //方向操作函数
    void(*Enable)(TMC2660ENNType enn);     //使能操作函数
 
    CurveObjectType curve;          //电机调速曲线
}TMC2660ObjectType;

2.1.2 、对象初始化

我们定义了对象类型,可以实现基于对象的操作,但定义的对象变量需要进行初始化才能让不同的对象按照我们的配置的方式去运行。所以在开始对象的使用之前我们先对其进行初始化,具体的初始化函数如下:

/*初始化TMC2660对象*/
void Tmc2660Initialization(TMC2660ObjectType*tmc,       //待初始化的TMC对象变量
                       TMC2660SdoffType interface,      //驱动接口类型
                       TMC2660MicroStepTypemicroStep,  //微步设置
                       uint16_t Power,                  //电流量程
                       uint16_t stepAngle,                 //固有步进角
                       uint16_t*pStartStop,            //启停操作命令
                       uint16_t*pDirection,            //方向控制
                       uint16_t*pRotateSet,            //转速设定
                       uint16_t *pMotorState,           //电机状态
                       TMC2660WriteReadTypewriteRead,  //读写函数指针
                       TMC2660ChipSelcetTypecs,        //片选操作函数指针
                       TMC2660StartStopTypestartStop,  //启停操作函数指针
                       TMC2660DirectTypedirect,        //方向设置函数指针
                       TMC2660EnableTypeenable         //使能控制函数指针
                       )
{
   uint32_t MicroStep[9]={0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00};
   uint16_t MicroStepNum[9]={1,2,4,8,16,32,64,128,256};
   
   if((tmc==NULL)||(writeRead==NULL)||(cs==NULL)||(enable==NULL))
    {
       return;
    }
   
   tmc->WriteRead=writeRead;
   tmc->ChipSelcet=cs;
   tmc->StartStop=startStop;
   tmc->Direct=direct;
   tmc->Enable=enable;
   
   tmc->pStartStop=pStartStop;
   tmc->pDirection=pDirection;
   tmc->pRotateSet=pRotateSet;
   tmc->pMotorState=pMotorState;
   
   tmc->microStep=MicroStepNum[microStep];
   tmc->stepAngle=(float)stepAngle/10.0;
   
   tmc->curve.stepSpeed=0.02;
   tmc->curve.currentSpeed=0;
   tmc->curve.startSpeed=0;
   tmc->curve.speedMax=300;
   tmc->curve.speedMin=1.0;
   tmc->curve.curveMode=CURVE_SPTA;
   tmc->curve.flexible=10.0;
 
   tmc->Register[Reg_DRVCTRL]=DRVCTRL;
   tmc->Register[Reg_CHOPCONF]=CHOPCONF;
   tmc->Register[Reg_SMARTEN]=SMARTEN;
   tmc->Register[Reg_SGCSCONF]=SGCSCONF;
   tmc->Register[Reg_DRVCONF]=DRVCONF;
   
   tmc->Register[Reg_CHOPCONF]=tmc->Register[Reg_CHOPCONF]|0x1B1;
   tmc->Register[Reg_SMARTEN]=tmc->Register[Reg_SMARTEN]|0x202;
   tmc->Register[Reg_SGCSCONF]=tmc->Register[Reg_SGCSCONF]|0x10000;
   
   WriteReadTmc2660Register(tmc,Reg_CHOPCONF);
   WriteReadTmc2660Register(tmc,Reg_SGCSCONF);
   
   if(interface==TMC2660_SPI)
   {
       tmc->Register[Reg_DRVCONF]=tmc->Register[Reg_DRVCONF]|0xA190;
       WriteReadTmc2660Register(tmc,Reg_DRVCONF);
    }
    else
    {
       tmc->Register[Reg_DRVCONF]=tmc->Register[Reg_DRVCONF]|0xA140;
       WriteReadTmc2660Register(tmc,Reg_DRVCONF);
       
       tmc->Register[Reg_DRVCTRL]=tmc->Register[Reg_DRVCTRL]|0x100|MicroStep[microStep];
       WriteReadTmc2660Register(tmc,Reg_DRVCTRL);
    }
   
   WriteReadTmc2660Register(tmc,Reg_SMARTEN);
   
   SetMotorPower(tmc,Power);
}

2.2 、对象操作

接下来我们考虑对TMC2660进行的操作问题。我们已经知道TMC2660拥有5个寄存器,而对TMC2660的各种配置都是通过这5个寄存器来实现的。即使使用SD模式来实现电机驱动也是通过寄存器配置才能实现,所以对TMC2660基本的操作则是读写TMC2660寄存器。至于SD模式下,输入脉冲和方向信号依赖于具体平台,我们已将其定义为对象的回调函数。

/*读写寄存器*/
static voidWriteReadTmc2660Register(TMC2660ObjectType *tmc,TMC2660RegType reg)
{
    uint8_t wData[3];
    uint8_t rData[3];
    uint32_t status=0;
    uint32_t regValue;
   
    tmc->ChipSelcet(TMC2660CS_Enable);
   
   regValue=tmc->Register[reg]&0xFFFFF;
   wData[0]=(uint8_t)(regValue>>16);
   wData[1]=(uint8_t)(regValue>>8);
   wData[2]=(uint8_t)regValue;
   
   tmc->WriteRead(wData,3,rData,3);
   
   status=rData[0];
   status=(status<<8)+rData[1];
   status=(status<<8)+rData[2];
   
   tmc->status= status;
   
   tmc->ChipSelcet(TMC2660CS_Disable);
}

3 、驱动的应用

我们已经设计并实现了TMC2660步进电机驱动芯片的驱动程序,接下来我们实现一个实例来验证这一驱动设定是否符合要求。

3.1 、声明并初始化对象

在开始一切操作之前,首先我们需要一个对象。前面的设计中,我们已经定义了一个TMC2660对象类型,所以我们使用它定义一个对象变量。

TMC2660ObjectType tmc;

定义了tmc对象变量之后,还没有办法使用,因为我们需要对其进行初始化。前面我们已经设计了对象初始化函数,我们需要使用它来初始化tmc对象变量。初始化函数需要如下参数:

TMC2660ObjectType *tmc, //待初始化的TMC对象变量

TMC2660SdoffType interface, //驱动接口类型

TMC2660MicroStepType microStep, //微步设置

uint16_t Power, //电流量程

uint16_t stepAngle, //固有步进角

uint16_t *pStartStop, //启停操作命令

uint16_t *pDirection, //方向控制

uint16_t *pRotateSet, //转速设定

uint16_t *pMotorState, //电机状态

TMC2660WriteReadType writeRead, //读写函数指针

TMC2660ChipSelcetType cs, //片选操作函数指针

TMC2660StartStopType startStop, //启停操作函数指针

TMC2660DirectType direct, //方向设置函数指针

TMC2660EnableType enable //使能控制函数指针

在这些参数中,操作变量将具体的变量指针传入即可,而其它参数如接口类型,步距角等则根据具体的应用情况输入即可。需要注意的是,5歌操作函数指针,其函数原型定义如下:

typedef void (*TMC2660WriteReadType)(uint8_t*wData,uint16_t wSize,uint8_t *rData,uint16_t rSize);
typedef void(*TMC2660ChipSelcetType)(TMC2660CSType cs);    //片选信号
typedef void(*TMC2660StartStopType)(TMC2660SSType ss);        //启停操作函数
typedef void (*TMC2660DirectType)(TMC2660DIRTypedir);     //方向操作函数
typedef void (*TMC2660EnableType)(TMC2660ENNTypeenn);     //使能操作函数

这些操作函数依赖于具体的操作平台,我们采用的是已于STM32F103CBT6和HAL库函数的操作平台,所以根据函数原型定义来收集这些函数如下:

/*TMC2660片选操作函数*/
static void TMC2660ChipSelcet(TMC2660CSType cs)
{
   if(cs==TMC2660CS_Enable)
    {
       TMC_CSN_ENABLE();
    }
    else
    {
       TMC_CSN_DISABLE();
    }
}
 
/*启停操作函数*/
static void MotorStartStop(TMC2660SSType ss)
{
   if(ss==TMC2660SS_Start)
    {
       if(HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3) != HAL_OK)
        {
        }
    }
    else
    {
       if(HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_3) != HAL_OK)
        {
        }
    }
}
 
/*方向操作函数*/
static void MotorDirect(TMC2660DIRType dir)
{
   if(dir==TMC2660DIR_CCW)
    {
       TMC_DIR_DISABLE();
    }
    else
    {
       TMC_DIR_ENABLE();
    }
}
 
/*使能操作函数*/
static void TMC2660Enable(TMC2660ENNType enn)
{
   if(enn==TMC2660ENN_Enable)
    {
       TMC_ENN_ENABLE();
    }
    else
    {
       TMC_ENN_DISABLE();
    }
}
 
/*通过SPI2端口读写数据*/
static void WriteReadBySPI2(uint8_t*wData,uint16_t wSize,uint8_t *rData,uint16_t rSize)
{
   HAL_SPI_TransmitReceive (&hspi2, wData, rData, wSize, 1000);
}

至此,我们已经明白了初始化函数所需要的全部参数,我们可以使用改初始换函数初始化tmc对象变量如下:

/*初始化TMC2660对象*/
   Tmc2660Initialization(&tmc,
                         TMC2660_SD,
                         MicroStep_256,
                         aPara.phyPara.sm42PowerRange,
                         aPara.phyPara.sm42StepAngle,
                         &aPara.phyPara.sm42StartStop,
                         &aPara.phyPara.sm42Direction,
                         &aPara.phyPara.sm42RotateSet,
                         &aPara.phyPara.sm42RunStatus,
                         WriteReadBySPI2,
                         TMC2660ChipSelcet,
                         MotorStartStop,
                         MotorDirect,
                         TMC2660Enable
                         );

3.2 、基于对象进行操作

初始化之后,我们就可以使用该对象来事项我们想要的操作了。我们设计一个应用函数调用相关驱动实现操作,并判断速度的设定是否改变来决定是否调整电机的运行速度。

/* 步进电机驱动控制处理函数 */
void SM42Tmc2660Driver(void)
{
    float temp=0;
       
   if(aPara.phyPara.sm42RotateSet<=0)
    {
       //return;
     aPara.phyPara.sm42StartStop=0;
    }
   
   Tmc2660ControlBySD(&tmc);
   
   SpeedSet(tmc.frequency);
   
    //计算转速
   temp=tmc.frequency*((float)aPara.phyPara.sm42StepAngle);
   temp=temp/((float)aPara.phyPara.sm42MicroStep);
   aPara.phyPara.sm42RotateSpeed=(uint16_t)(temp*100/30.0);
}
 
/* 速度调整函数 */
static void SpeedSet(float freq)
{
   uint16_t period=0;
   float temp=24000000;
   
   if(freq>0)
    {
       temp=temp/freq;
       period=(uint16_t)temp;
       
       if((2<=period)&&(period<65535))
        {
           __HAL_TIM_SET_AUTORELOAD(&htim1,period-1);
           __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_3,period/2-1);
        }
    }
    else
    {
       __HAL_TIM_SET_AUTORELOAD(&htim1,0);
        __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_3,0);
    }
}

4 、应用总结

在本篇中,我们设计并实现了TMC2660的驱动程序,并基于驱动程序设计了一个验证程序,测试结果良好。事实上,该驱动已经使用到我们的多个项目之中,运行效果目前还是不错的。

在使用驱动程序时需要注意,片选信号并非必须实现。因为有些时候我们可能需要在硬件上直接将其选中,此时添加片选操作函数是没有什么意义的,我们可以在初始化时传入NULL来完成。

在配置TMC2660的寄存器时,一定要仔细根据自己的应用需求来配置,如电流保护、波形输出等这些参数的配置对力矩以及电机的运行噪声有很大关系,所以需要特别注意。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 步进电机
    +关注

    关注

    150

    文章

    3091

    浏览量

    147285
  • 驱动设计
    +关注

    关注

    1

    文章

    110

    浏览量

    15261
  • 驱动芯片
    +关注

    关注

    13

    文章

    1245

    浏览量

    54402
收藏 人收藏

    评论

    相关推荐

    步进驱控芯片TMC2660-PA

    TMC2660驱动4A峰值电流的步进电机芯片解决方案,该方案工作能耗只有2.8瓦。4A电流的步进
    发表于 08-31 17:25

    TMC2660驱动控制步进电机

    TMC2660可以通过SPI接口或者DIR/STEP接口对步进电机驱动控制,然后控制器是STM32F103,如果使用SPI接口进行驱动时,要
    发表于 11-12 15:25

    步进电机驱动相序线接反为什么还能正常转动

    如图a->b->c->d 通电顺时针转动,d->c->b->a 通电逆时针转动,现在把A和A-两根线接反了,电机为什么还是能正常转动,用的是TMC2660这个驱动芯片
    发表于 12-19 14:37

    TMC2660驱动芯片步进电机驱动有哪些功能

    TMC2660驱动芯片步进电机驱动有哪些功能?步进
    发表于 07-07 07:33

    电机驱动芯片比较

    一、测试环境分别在同一电机,同一导轨上测试不同电机驱动芯片的性能。电机为新购买的带丝杆的电机
    发表于 09-07 06:16

    TMC2660通过SPI进行芯片参数的控制

    TMC2660通过SPI进行芯片参数的控制,一共需要初始化5个参数,具体参数含义可在数据手册上查到,这里不再做过多解释。直接贴代码,根据自己的平台自行移植即可。#defineREG_DRVCTRL 0X00000000#defineREG_CHOPCONF0X000800
    发表于 09-15 07:50

    如何实现TMC260/TMC2660/TMC262步进电机驱动

    spi配置参数有哪些?如何实现TMC260/TMC2660/TMC262步进电机驱动
    发表于 12-21 07:32

    TRINAMIC推出全新4安培步进电机驱动芯片

    近日,全球领先电机与运动控制开发者TRINAMIC发布一款全新的步进电机驱动芯片驱动电流达到4
    发表于 07-23 14:32 2332次阅读

    静音步进电机驱动控制芯片TMC5160资料

    本文档内容介绍了基于静音步进电机驱动控制芯片TMC5160资料,供参考
    发表于 02-27 10:35 118次下载

    电机精密运动控制专家电机驱动芯片TMC260

    型号TCM260是德国TRINAMIC公司产的步进电机驱动芯片,综合性能应该是步进电机
    的头像 发表于 07-18 14:36 1888次阅读
    <b class='flag-5'>电机</b>精密运动控制专家<b class='flag-5'>电机</b><b class='flag-5'>驱动</b><b class='flag-5'>芯片</b><b class='flag-5'>TMC</b>260

    基于TMC2660步进电机驱动

    TMC2660是德国TRINAMIC公司产的步进电机驱动芯片TMC2660
    发表于 03-16 09:28 6次下载
    基于<b class='flag-5'>TMC2660</b>的<b class='flag-5'>步进</b><b class='flag-5'>电机</b><b class='flag-5'>驱动</b>

    步进电机驱动芯片TMC260

    型号TCM260是德国TRINAMIC公司产的步进电机驱动芯片,综合性能应该是步进电机
    发表于 03-17 15:34 2次下载
    <b class='flag-5'>步进</b><b class='flag-5'>电机</b><b class='flag-5'>驱动</b><b class='flag-5'>芯片</b><b class='flag-5'>TMC</b>260

    TMC2160步进电机驱动芯片

    TMC2160是一款大功率步进电机驱动芯片,具有SPI接口。它采用了业界最先进的步进
    的头像 发表于 06-02 10:52 1454次阅读
    <b class='flag-5'>TMC</b>2160<b class='flag-5'>步进</b><b class='flag-5'>电机</b><b class='flag-5'>驱动</b><b class='flag-5'>芯片</b>

    极具性价比的步进电机驱动芯片-TMC2226/TMC2209使用小结

    TMC2226/2209相对于TMC2660C、TMC5160来说,价格低了很多,同时功能并没有太多阉割。 对比TMC5160,少了内部加减速曲线,电流足够(Ipeak = 2.8A
    的头像 发表于 07-30 09:30 3526次阅读
    极具性价比的<b class='flag-5'>步进</b><b class='flag-5'>电机</b><b class='flag-5'>驱动</b><b class='flag-5'>芯片</b>-<b class='flag-5'>TMC</b>2226/<b class='flag-5'>TMC</b>2209使用小结

    TMC2226单轴步进电机驱动芯片2A工作电流

    Trinamic电机驱动芯片TMC2226单轴步进电机驱动
    的头像 发表于 04-04 08:26 798次阅读
    <b class='flag-5'>TMC</b>2226单轴<b class='flag-5'>步进</b><b class='flag-5'>电机</b><b class='flag-5'>驱动</b><b class='flag-5'>芯片</b>2A工作电流