步進電機的應用非常廣泛,在各種設備中經常會遇到,而步進電機的驅動則是使用步進電機必不可少的部分,可以有多種方式來實現步進電機的驅動,在這里我們來考慮一下基于TMC2660驅動芯片的步進電機驅動。
1 、功能概述
TMC2660是德國TRINAMIC公司產的步進電機驅動芯片。TMC2660驅動器提供了業界領先的功能集,包括高分辨率微步、無傳感器機械負載測量、負載自適應功率優化和低共振斬波操作。擁有標準SPI和STEP/DIR兩種接口模式。集成功率MOSFET處理電機電流高達2.2A。集成的保護和診斷功能支持穩健和可靠的運行。其結構圖如下:
TMC2660的參數配置通過SPI接口來實現。TMC2660具有5個配置和控制寄存器,通過SPI端口來訪問這些寄存器。這些寄存器的結構定義如下所示:
所有的寄存器都是20位,在最高的2位或3位表示的是寄存器地址也稱為操作碼。根據具體的寄存器我們選擇不同的操作碼實現對寄存器的寫操作。每一個寫操作都會有一個20位的數據返回。而返回數據的內容可以通過修改配置寄存器來定義。具體的格式如下圖所示:
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文章
3042瀏覽量
146855 -
驅動設計
+關注
關注
1文章
109瀏覽量
15235 -
驅動芯片
+關注
關注
13文章
1224瀏覽量
54147
發布評論請先 登錄
相關推薦
評論