1. 程式人生 > >TMC260/TMC2660/TMC262步進電機驅動

TMC260/TMC2660/TMC262步進電機驅動

1.TMC260
  TCM260是德國TRINAMIC公司產的步進電機驅動晶片,綜合性能應該是步進電機驅動晶片中排前列的,當然價格也是。TMC260程式上相容TMC2660、TMC262,其中TMC2660是比較新的型號,驅動電流也比TMC260要大;TMC262是外接mos管,可驅動大功率步進電機,如57步進電機等。在之前“用過的幾款步進電機驅動IC”的文章中,有簡單介紹過,因此有壇友發私信或者留言詢問該晶片的驅動程式,所以總結下自己的使用經驗。

  其實整合步進電機驅動晶片,對於驅動電機來說是非常簡易,通過脈衝方波或者匯流排(spi、i2c)傳送指令即可驅動。TMC260也不例外,TMC260有兩種驅動電機轉動的方式,一是通過脈衝方波,二是通過spi介面傳送指令。但是TMC260中有關引數的設定必須通過spi介面進行操作,如電流大小(力矩)、細分步矩角以及獲取狀態資訊等。

  對於spi傳送命令的控制方式,可能會存在延時,特別是一類匯流排為了便於使用者層呼叫,對spi匯流排進行了多層封裝的情況下,如在RTOS中。為提高電機速度,鄙人用的是第一種方式,通過脈衝方波控制電機轉動,電機的相關引數則通過spi匯流排設定或者獲取。對於轉動控制則比較好理解和實現,通過定時器或者PWM輸出控制“STEP”引腳即可,脈衝頻率的高低控制轉動速度的快慢;控制方向通過普通IO口控制“DIRECT”引腳高低電平切換,故這塊不作贅述。下面重點介紹下spi配置引數方面,如果引數沒有正確配置,也是無法控制電機轉動或者出現轉動噪音大的情況。

2.TMC260 SPI匯流排實現


  spi匯流排依然是基於“spi抽象/硬體spi”中的spi封裝函式。
首先定義TMC260 spi匯流排指標裝置和TMC260指標裝置。
  原始碼中,命名是TMC2660,因為後面更換使用為TMC2660,但程式完全相容。

static struct spi_dev_device    tmc2660_spi_dev[1];//暫時只有一個電機
static struct spi_bus_device    spi_bus0;

第二步,實現spi 匯流排片選函式,即是普通IO口翻轉。

static void spi0_cs(unsigned char state)
{
    if (state)
        GPIO_SetBits(TMC2660_PORTY_CS, TMC2660_GPIOY_CS);
    else
GPIO_ResetBits(TMC2660_PORTY_CS, TMC2660_GPIOY_CS); }

第三步,TMC260收發函式實現。

static u32 tmc2660_spi_xfer(u8 spi_no,u32 write_data)
{
    u8 send_buff[3],recv_buff[3];
    u32 recv_data= 0;

    send_buff[0] = (write_data>>16)&0xff;
    send_buff[1] = (write_data>>8)&0xff;
    send_buff[2
] = (write_data&0xff); spi_send_recv(&tmc2660_spi_dev[spi_no],send_buff,recv_buff,3); recv_data = recv_buff[0]<<16 | recv_buff[1]<<8 | recv_buff[2]; return (recv_data&0x0fffff); }

其中:
—TMC260 spi是非標spi,一幀完整的資料是20bit,可以通過硬體spi驅動,無效位會自動忽略,如下圖,從手冊中獲悉,使用24bit(3位元組)傳輸,高4bit會自動忽略。所以這裡還是用硬體spi。
這裡寫圖片描述
—20bit的資料,spi設定為8bit模式,所以最少需要3位元組(24bit)的快取。
—返回值即是晶片的狀態資訊,每發一幀都會有相關資訊返回。
—輸入引數,分別是spi埠號和待寫的資料。
—從時序圖分析,用到的是spi封裝函式中的“spi_send_recv”,即是傳送完成同時也完成資料的接收,效率非常高。

3.TMC260 暫存器配置
  TMC260嚴格來說沒有標準暫存器,在一串20bit的序列資料流中,以高3位選擇不同的功能,後面17位表示資料,包括寫入或者返回的狀態資料。
這裡寫圖片描述
  每一個暫存器都有詳細的描述和使用方式,程式碼中進行巨集定義。

#define     REG_DRVCTRL         0X00000000
#define     REG_CHOPCONF        0X00080000
#define     REG_SMARTEN         0X000A0000
#define     REG_SGCSCONF        0X000C0000
#define     REG_DRVCONF         0X000E0000

1)REG_DRVCTRL
  控制暫存器,如設定電流細分,其中細分數從1到256。

#define     MICROSTEP_256       0X00
#define     MICROSTEP_128       0X01
#define     MICROSTEP_64        0X02
#define     MICROSTEP_32        0X03
#define     MICROSTEP_16        0X04
#define     MICROSTEP_8         0X05
#define     MICROSTEP_4         0X06
#define     MICROSTEP_2         0X07
#define     MICROSTEP_1         0X08

  函式如下:

void tmc2660_set_subdivide(char mode,u8 motor_index)
{
        u8  step = 0;
        u32 cmd = 0;

        switch(mode)
        {
                case 0:
                        step = MICROSTEP_1;
                break;
                case 1:
                        step = MICROSTEP_2;
                break;
                case 2:
                        step = MICROSTEP_4;
                break;
                case 3:
                        step = MICROSTEP_8;
                break;
                case 4:
                        step = MICROSTEP_16;
                break;
                case 5:
                        step = MICROSTEP_32;
                break;
                case 6:
                        step = MICROSTEP_64;
                break;
                case 7:
                        step = MICROSTEP_128;
                break;
                case 8:
                        step = MICROSTEP_256;
                break;
                default:
                        step = MICROSTEP_16;
                break;
        }
        cmd = REG_DRVCTRL | step;
        tmc2660_spi_xfer(motor_index,cmd);
}

2)REG_CHOPCONF 暫未用到。
3)REG_SMARTEN 智慧設定,預設自動模式,暫未用到。
4)REG_SGCSCONF
  配置暫存器,如設定最大輸出電流,即是電機力矩。

void tmc2660_set_force(u8 force,u8 motor_index)
{
        u8 temp;
        int cmd = 0;

        temp = force/8;
        cmd = REG_SGCSCONF | SCG_DEFAULT | temp;
        tmc2660_spi_xfer(motor_index,cmd);
}

5)REG_DRVCONF
動力相關配置暫存器,如可以選擇大電流模式,或者普通模式。
大電流模式:

tmc2660_spi_xfer(0,REG_DRVCONF | 0X0010); 

普通模式:

tmc2660_spi_xfer(0,REG_DRVCONF | 0X0050);


4.TMC260初始化

void tmc2660_init(u8 motor_index)
{       
    GPIO_InitTypeDef GPIO_InitStructure;

    //spi io
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC,ENABLE);
    //spi cs PA4
    GPIO_InitStructure.GPIO_Pin = TMC2660_GPIOY_CS;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(TMC2660_PORTY_CS, &GPIO_InitStructure);
    //device init
    stm32f1xx_spi_init(&spi_bus0,8,0,0);
    tmc2660_spi_dev[0].spi_cs = spi0_cs;
    tmc2660_spi_dev[0].spi_bus = &spi_bus0;     
    //enable 
    GPIO_InitStructure.GPIO_Pin = TMC2660_GPIOY_EN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                    
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   
    GPIO_Init(TMC2660_PORTY_EN,&GPIO_InitStructure);
    //step  
    GPIO_InitStructure.GPIO_Pin = TMC2660_GPIOY_STEP;                                       
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     //推輓輸出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   
    GPIO_Init(TMC2660_PORTY_STEP,&GPIO_InitStructure);
    //dir  
    GPIO_InitStructure.GPIO_Pin = TMC2660_GPIOY_DIR;                                        
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                    
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   
    GPIO_Init(TMC2660_PORTY_DIR,&GPIO_InitStructure);

    //原點光電開關 PB11
    GPIO_InitStructure.GPIO_Pin =  SenseY_GPIO;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   //上拉輸入
    GPIO_Init(SenseY_PORT, &GPIO_InitStructure);

    TMC2660_OUTY_CS     = 1;
    TMC2660_OUTY_EN     = 0;                                                                        //enable
    TMC2660_OUTY_DIR    = 0;                                                                        //正反轉控制

    tmc2660_spi_xfer(YMOTOR,REG_DRVCONF | 0X0050); //0X0010->305mV  0X0050->165mV 與電機電流相關
    tmc2660_spi_xfer(YMOTOR,REG_DRVCTRL | MICROSTEP_16);
    tmc2660_spi_xfer(YMOTOR,0x901b4);   //0x94557
    tmc2660_spi_xfer(YMOTOR,0xa0202);   //0xa0202->1/2CS 0xa8202->1/4CS 
    tmc2660_spi_xfer(YMOTOR,REG_SGCSCONF | SCG_DEFAULT | 0x00); //後5位為電流大小
    tmc2660_set_force(0,YMOTOR);
    tmc2660_set_subdivide(0x04,YMOTOR);
}

主要功能包括:
1)IO口初始化,步進控制、方向控制、使能控制、原點位置等IO口初始化。
2)spi匯流排指標初始化。
3)TMC2660控制晶片預設引數配置。

5.原始碼
[1] https://github.com/Prry/drivers-for-mcu