步進(jìn)電機(jī)的應(yīng)用非常廣泛,在各種設(shè)備中經(jīng)常會(huì)遇到,而步進(jìn)電機(jī)的驅(qū)動(dòng)則是使用步進(jìn)電機(jī)必不可少的部分,可以有多種方式來實(shí)現(xiàn)步進(jìn)電機(jī)的驅(qū)動(dòng),在這里我們來考慮一下基于TMC2660驅(qū)動(dòng)芯片的步進(jìn)電機(jī)驅(qū)動(dòng)。
1 、功能概述
TMC2660是德國(guó)TRINAMIC公司產(chǎn)的步進(jìn)電機(jī)驅(qū)動(dòng)芯片。TMC2660驅(qū)動(dòng)器提供了業(yè)界領(lǐng)先的功能集,包括高分辨率微步、無傳感器機(jī)械負(fù)載測(cè)量、負(fù)載自適應(yīng)功率優(yōu)化和低共振斬波操作。擁有標(biāo)準(zhǔn)SPI和STEP/DIR兩種接口模式。集成功率MOSFET處理電機(jī)電流高達(dá)2.2A。集成的保護(hù)和診斷功能支持穩(wěn)健和可靠的運(yùn)行。其結(jié)構(gòu)圖如下:
TMC2660的參數(shù)配置通過SPI接口來實(shí)現(xiàn)。TMC2660具有5個(gè)配置和控制寄存器,通過SPI端口來訪問這些寄存器。這些寄存器的結(jié)構(gòu)定義如下所示:
所有的寄存器都是20位,在最高的2位或3位表示的是寄存器地址也稱為操作碼。根據(jù)具體的寄存器我們選擇不同的操作碼實(shí)現(xiàn)對(duì)寄存器的寫操作。每一個(gè)寫操作都會(huì)有一個(gè)20位的數(shù)據(jù)返回。而返回?cái)?shù)據(jù)的內(nèi)容可以通過修改配置寄存器來定義。具體的格式如下圖所示:
2 、驅(qū)動(dòng)設(shè)計(jì)于實(shí)現(xiàn)
我們已經(jīng)了解了TMC2660步進(jìn)電機(jī)驅(qū)動(dòng)芯片的基本技術(shù)參數(shù),接下來我們就需要據(jù)此來實(shí)現(xiàn)TMC2660步進(jìn)電機(jī)驅(qū)動(dòng)芯片的驅(qū)動(dòng)程序的設(shè)計(jì)與實(shí)現(xiàn)。
2.1 、對(duì)象定義
我們依然是居于對(duì)象來實(shí)現(xiàn)相關(guān)的操作。所以我們首先要定義對(duì)象,出于適用性考慮,我們要定義對(duì)象的類型并將具體的對(duì)象實(shí)例化,接下來我們就來抽象對(duì)象類型和實(shí)例化對(duì)象的操作。
2.1.1 、對(duì)象的抽象
對(duì)于一個(gè)對(duì)象最主要包括屬性與操作兩方面內(nèi)容,所以我們先來考慮TMC2660對(duì)象具有哪些屬性和操作,并抽象出較為通用的TMC2660對(duì)象類型。
對(duì)于步進(jìn)電機(jī)的驅(qū)動(dòng)都具有哪些屬性呢?我們考慮到一臺(tái)步進(jìn)電機(jī)至少具備啟停控制命令、方向控制命令、速度設(shè)定以及運(yùn)行狀態(tài)等,這些對(duì)于每一臺(tái)步進(jìn)電機(jī)來說,在不同的設(shè)置下代表不同的狀態(tài),所以我們將其作為其屬性來處理。此外,與具體的電機(jī)相關(guān)的參數(shù)如固有步距角、微步設(shè)置及當(dāng)前脈沖頻率等。以及與TMC2660相關(guān)的狀態(tài)、寄存器的值、速度規(guī)劃等都與具體的應(yīng)用需求相關(guān)、用以記錄其運(yùn)行和配置狀態(tài),所以我們將其作為屬性。
然后再來看一看TMC2660對(duì)象需要實(shí)現(xiàn)的操作。對(duì)于TMC2660對(duì)象來說,我們要操作它,需要向其發(fā)送和讀取數(shù)據(jù),需要操作片選信號(hào)和使能信號(hào),而這些行為依賴于具體的操作平臺(tái),所以我們將其作為對(duì)象的操作來設(shè)定。TMC2660可以工作在SPI模式或者SD模式,而在SD模式時(shí),存在脈沖和方向的控制,這同樣依賴于具體的軟硬件操作平臺(tái),所以我們也將其作為對(duì)象的操作來實(shí)現(xiàn)。更具以上的分析我們可以抽象出TMC2660對(duì)象類型如下:
/*定義TMC2660對(duì)象類型*/
typedef struct TMC2660Object {
float microStep;//微步設(shè)置
float stepAngle;//固有步進(jìn)角
float frequency; //運(yùn)行頻率
uint16_t *pStartStop; //啟停操作命令
uint16_t *pDirection; //方向控制
uint16_t *pRotateSet; //轉(zhuǎn)速設(shè)定
uint16_t *pMotorState; //電機(jī)狀態(tài)
uint32_t status; //TMC通訊返回狀態(tài)
uint32_t Register[5]; //寄存器
void (*WriteRead)(uint8_t*wData,uint16_t wSize,uint8_t *rData,uint16_t rSize);
void(*ChipSelcet)(TMC2660CSType cs); //片選信號(hào)
void(*StartStop)(TMC2660SSType ss); //啟停操作函數(shù)
void(*Direct)(TMC2660DIRType dir); //方向操作函數(shù)
void(*Enable)(TMC2660ENNType enn); //使能操作函數(shù)
CurveObjectType curve; //電機(jī)調(diào)速曲線
}TMC2660ObjectType;
2.1.2 、對(duì)象初始化
我們定義了對(duì)象類型,可以實(shí)現(xiàn)基于對(duì)象的操作,但定義的對(duì)象變量需要進(jìn)行初始化才能讓不同的對(duì)象按照我們的配置的方式去運(yùn)行。所以在開始對(duì)象的使用之前我們先對(duì)其進(jìn)行初始化,具體的初始化函數(shù)如下:
/*初始化TMC2660對(duì)象*/
void Tmc2660Initialization(TMC2660ObjectType*tmc, //待初始化的TMC對(duì)象變量
TMC2660SdoffType interface, //驅(qū)動(dòng)接口類型
TMC2660MicroStepTypemicroStep, //微步設(shè)置
uint16_t Power, //電流量程
uint16_t stepAngle, //固有步進(jìn)角
uint16_t*pStartStop, //啟停操作命令
uint16_t*pDirection, //方向控制
uint16_t*pRotateSet, //轉(zhuǎn)速設(shè)定
uint16_t *pMotorState, //電機(jī)狀態(tài)
TMC2660WriteReadTypewriteRead, //讀寫函數(shù)指針
TMC2660ChipSelcetTypecs, //片選操作函數(shù)指針
TMC2660StartStopTypestartStop, //啟停操作函數(shù)指針
TMC2660DirectTypedirect, //方向設(shè)置函數(shù)指針
TMC2660EnableTypeenable //使能控制函數(shù)指針
)
{
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 、對(duì)象操作
接下來我們考慮對(duì)TMC2660進(jìn)行的操作問題。我們已經(jīng)知道TMC2660擁有5個(gè)寄存器,而對(duì)TMC2660的各種配置都是通過這5個(gè)寄存器來實(shí)現(xiàn)的。即使使用SD模式來實(shí)現(xiàn)電機(jī)驅(qū)動(dòng)也是通過寄存器配置才能實(shí)現(xiàn),所以對(duì)TMC2660基本的操作則是讀寫TMC2660寄存器。至于SD模式下,輸入脈沖和方向信號(hào)依賴于具體平臺(tái),我們已將其定義為對(duì)象的回調(diào)函數(shù)。
/*讀寫寄存器*/
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 、驅(qū)動(dòng)的應(yīng)用
我們已經(jīng)設(shè)計(jì)并實(shí)現(xiàn)了TMC2660步進(jìn)電機(jī)驅(qū)動(dòng)芯片的驅(qū)動(dòng)程序,接下來我們實(shí)現(xiàn)一個(gè)實(shí)例來驗(yàn)證這一驅(qū)動(dòng)設(shè)定是否符合要求。
3.1 、聲明并初始化對(duì)象
在開始一切操作之前,首先我們需要一個(gè)對(duì)象。前面的設(shè)計(jì)中,我們已經(jīng)定義了一個(gè)TMC2660對(duì)象類型,所以我們使用它定義一個(gè)對(duì)象變量。
TMC2660ObjectType tmc;
定義了tmc對(duì)象變量之后,還沒有辦法使用,因?yàn)槲覀冃枰獙?duì)其進(jìn)行初始化。前面我們已經(jīng)設(shè)計(jì)了對(duì)象初始化函數(shù),我們需要使用它來初始化tmc對(duì)象變量。初始化函數(shù)需要如下參數(shù):
TMC2660ObjectType *tmc, //待初始化的TMC對(duì)象變量
TMC2660SdoffType interface, //驅(qū)動(dòng)接口類型
TMC2660MicroStepType microStep, //微步設(shè)置
uint16_t Power, //電流量程
uint16_t stepAngle, //固有步進(jìn)角
uint16_t *pStartStop, //啟停操作命令
uint16_t *pDirection, //方向控制
uint16_t *pRotateSet, //轉(zhuǎn)速設(shè)定
uint16_t *pMotorState, //電機(jī)狀態(tài)
TMC2660WriteReadType writeRead, //讀寫函數(shù)指針
TMC2660ChipSelcetType cs, //片選操作函數(shù)指針
TMC2660StartStopType startStop, //啟停操作函數(shù)指針
TMC2660DirectType direct, //方向設(shè)置函數(shù)指針
TMC2660EnableType enable //使能控制函數(shù)指針
在這些參數(shù)中,操作變量將具體的變量指針傳入即可,而其它參數(shù)如接口類型,步距角等則根據(jù)具體的應(yīng)用情況輸入即可。需要注意的是,5歌操作函數(shù)指針,其函數(shù)原型定義如下:
typedef void (*TMC2660WriteReadType)(uint8_t*wData,uint16_t wSize,uint8_t *rData,uint16_t rSize);
typedef void(*TMC2660ChipSelcetType)(TMC2660CSType cs); //片選信號(hào)
typedef void(*TMC2660StartStopType)(TMC2660SSType ss); //啟停操作函數(shù)
typedef void (*TMC2660DirectType)(TMC2660DIRTypedir); //方向操作函數(shù)
typedef void (*TMC2660EnableType)(TMC2660ENNTypeenn); //使能操作函數(shù)
這些操作函數(shù)依賴于具體的操作平臺(tái),我們采用的是已于STM32F103CBT6和HAL庫(kù)函數(shù)的操作平臺(tái),所以根據(jù)函數(shù)原型定義來收集這些函數(shù)如下:
/*TMC2660片選操作函數(shù)*/
static void TMC2660ChipSelcet(TMC2660CSType cs)
{
if(cs==TMC2660CS_Enable)
{
TMC_CSN_ENABLE();
}
else
{
TMC_CSN_DISABLE();
}
}
/*啟停操作函數(shù)*/
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)
{
}
}
}
/*方向操作函數(shù)*/
static void MotorDirect(TMC2660DIRType dir)
{
if(dir==TMC2660DIR_CCW)
{
TMC_DIR_DISABLE();
}
else
{
TMC_DIR_ENABLE();
}
}
/*使能操作函數(shù)*/
static void TMC2660Enable(TMC2660ENNType enn)
{
if(enn==TMC2660ENN_Enable)
{
TMC_ENN_ENABLE();
}
else
{
TMC_ENN_DISABLE();
}
}
/*通過SPI2端口讀寫數(shù)據(jù)*/
static void WriteReadBySPI2(uint8_t*wData,uint16_t wSize,uint8_t *rData,uint16_t rSize)
{
HAL_SPI_TransmitReceive (&hspi2, wData, rData, wSize, 1000);
}
至此,我們已經(jīng)明白了初始化函數(shù)所需要的全部參數(shù),我們可以使用改初始換函數(shù)初始化tmc對(duì)象變量如下:
/*初始化TMC2660對(duì)象*/
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 、基于對(duì)象進(jìn)行操作
初始化之后,我們就可以使用該對(duì)象來事項(xiàng)我們想要的操作了。我們?cè)O(shè)計(jì)一個(gè)應(yīng)用函數(shù)調(diào)用相關(guān)驅(qū)動(dòng)實(shí)現(xiàn)操作,并判斷速度的設(shè)定是否改變來決定是否調(diào)整電機(jī)的運(yùn)行速度。
/* 步進(jìn)電機(jī)驅(qū)動(dòng)控制處理函數(shù) */
void SM42Tmc2660Driver(void)
{
float temp=0;
if(aPara.phyPara.sm42RotateSet<=0)
{
//return;
aPara.phyPara.sm42StartStop=0;
}
Tmc2660ControlBySD(&tmc);
SpeedSet(tmc.frequency);
//計(jì)算轉(zhuǎn)速
temp=tmc.frequency*((float)aPara.phyPara.sm42StepAngle);
temp=temp/((float)aPara.phyPara.sm42MicroStep);
aPara.phyPara.sm42RotateSpeed=(uint16_t)(temp*100/30.0);
}
/* 速度調(diào)整函數(shù) */
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 、應(yīng)用總結(jié)
在本篇中,我們?cè)O(shè)計(jì)并實(shí)現(xiàn)了TMC2660的驅(qū)動(dòng)程序,并基于驅(qū)動(dòng)程序設(shè)計(jì)了一個(gè)驗(yàn)證程序,測(cè)試結(jié)果良好。事實(shí)上,該驅(qū)動(dòng)已經(jīng)使用到我們的多個(gè)項(xiàng)目之中,運(yùn)行效果目前還是不錯(cuò)的。
在使用驅(qū)動(dòng)程序時(shí)需要注意,片選信號(hào)并非必須實(shí)現(xiàn)。因?yàn)橛行r(shí)候我們可能需要在硬件上直接將其選中,此時(shí)添加片選操作函數(shù)是沒有什么意義的,我們可以在初始化時(shí)傳入NULL來完成。
在配置TMC2660的寄存器時(shí),一定要仔細(xì)根據(jù)自己的應(yīng)用需求來配置,如電流保護(hù)、波形輸出等這些參數(shù)的配置對(duì)力矩以及電機(jī)的運(yùn)行噪聲有很大關(guān)系,所以需要特別注意。
-
步進(jìn)電機(jī)
+關(guān)注
關(guān)注
151文章
3115瀏覽量
147636 -
驅(qū)動(dòng)設(shè)計(jì)
+關(guān)注
關(guān)注
1文章
111瀏覽量
15294 -
驅(qū)動(dòng)芯片
+關(guān)注
關(guān)注
13文章
1292瀏覽量
54766
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論