步進馬達 驅動實例

實例:使用控制板 Arduino Mega 2560 控制步進馬達驅動板 TMC5130-EVAL 來驅動步進馬達。


圖 1 Arduino Mega2560 評估板


圖 2 TMC5130 馬達驅動板

圖 3 使用 Arduino Mega 控制步進馬達驅動板 TMC5130-EVAL

控制器: Arduino Mega 2560 是一款採用 ATmega2560 的微控制器板。它有 54 個數位輸入/輸出接腳(其中 15 個可以用作 PWM 輸出)、16 個類比輸入、4 個 UART(硬體序列埠)、一個 16MHz 晶體振盪器、一個USB連接、一個電源插座、一個ICSP接頭和一個重定按鈕。它包含支持微控制器所需的一切;只需用USB纜線將其連接到電腦,或用交流到直流適配器或電池為其供電即可開始使用。

步進馬達驅動板 :TMC5130 是一個完全整合的步進馬達驅動器和控制器系統,允許從任何微控制器遠端控制步進馬達。它在硬體上實現了所有即時關鍵任務。一旦配置,馬達可以透過給出目標位置、命令歸航序列或給出目標速度來驅動。使用 TMC5130 的好處包括:易於使用,使用 256 微步的馬達精度,低馬達雜訊(無雜訊隱藏斬波器),無感測器失速檢測(stallGuard2),無階躍損耗,dcStep 和 coolStep、UART 或 SPI 控制介面的高效率,高電壓範圍、小外型尺寸,以及低部件數量。

1. 確保 Arduino Mega 與 TMC5130-EVAL 有電壓匹配

如果 Arduino 是 5V 控制板,則必須將 TMC5130-EVAL 上的一個電阻從位置 R3 重新定位到 R8。這將 TMC5130 的邏輯電平設置為 +5V。

2. 連線


圖 4 TMC5130 與 Arduino Mega 2560 連接(圖片來源於 Trinamic)

上圖的纜線顏色
+5V - >紅色
GND - >藍色
SDO - >黃色
SDI - >橙色
SCK - >白色
CSN - >灰色
DRV_ENN - >黑色
CLK16 - >綠色


圖 5 接腳對應的訊號(圖片來源於 Trinamic)

接腳對應的訊號,在 Arduino 程式碼的注釋部分記錄了配置。

ARDUINO 程式碼

下面的 Arduino 程式碼不需要任何額外的函式庫。SPI 函式庫是 Arduino IDE 附帶的,該程式初始化 TMC5130 並執行簡單的移動到位置週期。它將根據步進馬達的接線將 200 全步進馬達向一個方向旋轉 10轉,向另一個方向旋轉 10轉。請使用 TMC5130 規格表或 TMCL IDE 作為不同暫存器的參考。

Arduino 程式碼

#include <SPI.h>
#include “TMC5130_registers.h”

/* The trinamic TMC5130 motor controller and driver operates through an
* SPI interface. Each datagram is sent to the device as an address byte
* followed by 4 data bytes. This is 40 bits (8 bit address and 32 bit word).
* Each register is specified by a one byte (MSB) address: 0 for read, 1 for
* write. The MSB is transmitted first on the rising edge of SCK.
*
* Arduino Pins Eval Board Pins
* 51 MOSI 32 SPI1_SDI
* 50 MISO 33 SPI1_SDO
* 52 SCK 31 SPI1_SCK
* 25 CS 30 SPI1_CSN
* 17 DIO 8 DIO0 (DRV_ENN)
* 11 DIO 23 CLK16
* GND 2 GND
* +5V 5 +5V
*/

int chipCS = 25;
const byte CLOCKOUT = 11;
// const byte CLOCKOUT = 9; → Uncomment for UNO, Duemilanove, etc…
int enable = 17;

void setup() {
// put your setup code here, to run once:
pinMode(chipCS,OUTPUT);
pinMode(CLOCKOUT,OUTPUT);
pinMode(enable, OUTPUT);
digitalWrite(chipCS,HIGH);
digitalWrite(enable,LOW);

//set up Timer1
TCCR1A = bit (COM1A0); //toggle OC1A on Compare Match
TCCR1B = bit (WGM12) | bit (CS10); //CTC, no prescaling
OCR1A = 0; //output every cycle

SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV8);
SPI.setDataMode(SPI_MODE3);
SPI.begin();

Serial.begin(9600);

sendData(0x80,0x00000000); //GCONF

sendData(0xEC,0x000101D5); //CHOPCONF: TOFF=5, HSTRT=5, HEND=3, TBL=2, CHM=0 (spreadcycle)
sendData(0x90,0x00070603); //IHOLD_IRUN: IHOLD=3, IRUN=10 (max.current), IHOLDDELAY=6
sendData(0x91,0x0000000A); //TPOWERDOWN=10

sendData(0xF0,0x00000000); // PWMCONF
//sendData(0xF0,0x000401C8); //PWM_CONF: AUTO=1, 2/1024 Fclk, Switch amp limit=200, grad=1

sendData(0xA4,0x000003E8); //A1=1000
sendData(0xA5,0x000186A0); //V1=100000
sendData(0xA6,0x0000C350); //AMAX=50000
sendData(0xA7,0x000186A0); //VMAX=100000
sendData(0xAA,0x00000578); //D1=1400
sendData(0xAB,0x0000000A); //VSTOP=10

sendData(0xA0,0x00000000); //RAMPMODE=0

sendData(0xA1,0x00000000); //XACTUAL=0
sendData(0xAD,0x00000000); //XTARGET=0
}

void loop()
{
// put your main code here, to run repeatedly:
sendData(0xAD,0x0007D000); //XTARGET=512000 | 10 revolutions with micro step = 256
delay(20000);
sendData(0x21,0x00000000);
sendData(0xAD,0x00000000); //XTARGET=0
delay(20000);
sendData(0x21,0x00000000);
}

void sendData(unsigned long address, unsigned long datagram)
{
//TMC5130 takes 40 bit data: 8 address and 32 data

delay(100);
uint8_t stat;
unsigned long i_datagram;

digitalWrite(chipCS,LOW);
delayMicroseconds(10);

stat = SPI.transfer(address);

i_datagram |= SPI.transfer((datagram >> 24) & 0xff);
i_datagram <<= 8;
i_datagram |= SPI.transfer((datagram >> 16) & 0xff);
i_datagram <<= 8;
i_datagram |= SPI.transfer((datagram >> 8) & 0xff);
i_datagram <<= 8;
i_datagram |= SPI.transfer((datagram) & 0xff);
digitalWrite(chipCS,HIGH);

Serial.print(“Received: “);
PrintHex40(stat, i_datagram);
Serial.print(”\n”);
Serial.print(" from register: ");
Serial.println(address,HEX);
}

void PrintHex40(uint8_t stat, uint32_t data) // prints 40-bit data in hex with leading zeroes
{
char tmp[16];
uint16_t LSB = data & 0xffff;
uint16_t MSB = data >> 16;
sprintf(tmp, “0x%.2X%.4X%.4X”, stat, MSB, LSB);
Serial.print(tmp);

程式碼來源於:Trinamic 部落格(關於程式碼的問題,可以去Trinamic部落格上瞭解更多)

更多有關馬達技術文章,請點選以下連結,也歡迎大家在文未留言討論。