Ansteuerung von Schrittmotoren mit dem IMT901

F !! Dieser Abschnitt ist nur für die Vollversion des LPC-Experimentierboards relevant, bzw. wenn sie eine eigene Hardwarebeschaltung mit dem IMT901 (z. B. SMC42-Mo­dul) verwenden. !!

Die Firma Nanotec (www.nanotec.de) bietet den sehr leistungsfähigen Schrittmotorbau­stein IMT901 an. Dieser lässt sich sehr einfach vom µController, in diesem Fall vom P89LPC932, ansteuern. Eine ausführliche Beschreibung und die notwenige Hardwarebe­schal­tung zum IMT 901 finden sie im Kapitel 12.6 [2].

Erstellen sie ein Projekt, das die Geschwindigkeit des Schrittmotors regelt. Die Regelung soll über den Inkrementalgeber vorgenommen werden. Die aktuelle Frequenz soll auf der 7-Segment-Anzeige ausgegeben werden.

F !! Die Werte für die Grenzfre­quen­zen sind dem Datenblatt des jeweiligen Schritt­­motors zu entnehmen. !!

Projektname

Verzeichnis

Verwendete Sourcemodule

TestIMT901

Test_IMT901

Test_IMT901.c

 

..\Library

PortConfig.c, Encoder_Lib.c, TimerLibrary.c, I2C_Lib.c, SAA1064_Lib.c

Tabelle 61  Projekt TestIMT901

Die Grenzgeschwindigkeiten sind in den #define-Anweisungen „GRENZ_U“ und „GRENZ_O“ enthalten (siehe Listing 57, ). In „PCLK“ (siehe ) ist die Frequenz von PCLK eingetragen. In diesem Fall ist es der Wert bei Verwendung des RC-Oscillators. Wenn sie z. B. einen externen Quarz mit 12 MHz verwenden, muss der Wert „6000000“ eingetragen werden. In „RELOAD_TIME_U“ und „RELOAD_TIME“ wird der Re­loadwert berechnet. Es wird von Betriebsart 1 eines Timers ausgegangen. In den nach­folgenden drei Definitionen (siehe ƒ) werden die Portpins für die Ansteuerung des IMT901 definiert. In der Variablen „uiTime“ (siehe ) ist der Reloadwert für den Timer ent­­halten. In den lokalen Variablen von main() (siehe ) werden Zwischenwerte ge­spei­chert, die für die Ausgabe auf der 7-Segment LED benötigt werden. Nachdem der Timer0 gestartet wurde (siehe ), läuft das Programm in der while-Schleife. In der Va­ria­blen „uiFreq“ (siehe ) wird aus dem Reloadwert die aktuelle Frequenz am Portpin „btCLk“ ermittelt. Um den Wert auf der 7-Segment LED ausgeben zu können, muss er voher in ASCII konvertiert werden. Dies wird mit der Funktion „sprintf()“ er­reicht (siehe ˆ). Das Ergebnis der Wandlung wird im Array „ucBuf[]“ abgespeichert. Zudem gibt die Funktion zurück, wie viele Bytes gewandelt wurden. Dieser Wert wird in „ucLength“ gespeichert. Damit die Frequenzausgabe immer rechtsbündig ist, müssen noch führende Nullen eingefügt werden. Dies wird sehr einfach mit dem switch-case Kon­­strukt erreicht (siehe ). Im zweiten Konstrukt (siehe Š) erfolgt die eigentliche Aus­gabe der Frequenz. Vom gewandelten Wert wird der Wert 0x30 abgezogen, da die Funktion  „v_ConvVal()“ nur binäre Übergabewerte verarbeitet.

 

 

 

 

 

 

 

 

 

 

 

 

ƒ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ˆ

 

 

 

 

 

 

 

 

 

Š

 

 

 

 

 

#include <REG932.H>

#include <PortConfig.H>

#include <Encoder_Lib.h>

#include <TimerLibrary.h>

#include <I2C_LIB.H>

#include <SAA1064_LIB.h>

#include <stdio.h>

 

#define GRENZ_U 300   // Hz ti/T = 0.5

#define GRENZ_O 1000  // Hz ti/T = 0.5

 

#define PCLK 3686400  // Hz (RC-Oscillator/2) = PCLK

#define RELOAD_TIME_U ((PCLK/GRENZ_U)/2)

#define RELOAD_TIME_O ((PCLK/GRENZ_O)/2)

 

sbit btDir = P2^0;  // Pin-Definitionen fuer die Ansteuerung

sbit btEna = P2^1;  // des IMT901.

sbit btClk = P2^2;

 

unsigned int uiTime = (0xFFFF - RELOAD_TIME_U);

 

void main(void)

{

  unsigned int uiFreq;           // Hilfsvariablen für die Ausgabe                                         

  unsigned char ucBuf[5], ucLength, ucOff; //auf der 7-Segment LED

  v_InitI2C();

  v_InitEncoder();

  v_PortConfig(Port2, Pin0 | Pin1 | Pin2, PushPull);

  v_InitTimer0(MODE1 | TIMER);  // Initialisierung des Timers 1

 

  TH0 = uiTime/256;  // Setzen des Reloadwertes

  TL0 = (unsigned char) uiTime;

  TF0 = 0;

  ET0 = 1;

 

  btDir = 0;   // Initialisierung des IMT901

  btEna = 1;

  btClk = 0;

 

  EA = 1;      // allgemeine Interruptsperre aufheben

  v_InitSAA1064(DYNAMIC_MODE);

  TR0 = 1;     // Timer 0 starten

 

  while(1)

  { // aktuelle Frequenz berechnen und ausgeben

    uiFreq = 0xFFFF - uiTime *2;

    uiFreq = PCLK / uiFreq;

    ucLength = sprintf(ucBuf,"%u", uiFreq);

    Slave.DataLen = 0;   

    Slave.Adr = 0x70;      // Adresse SAA1064   

    v_SetNextI2CVal(1);    // Subadresse auf 1 (Daten-Byte)

    switch (ucLength)

    {

    case 0: v_ConvVal(0);

    case 1: v_ConvVal(0);

    case 2: v_ConvVal(0);

    case 3: v_ConvVal(0);

    }

    ucOff = 0;

    switch (ucLength)

    {

    case 4: v_ConvVal(ucBuf[ucOff++] - 0x30);

    case 3: v_ConvVal(ucBuf[ucOff++] - 0x30);

    case 2: v_ConvVal(ucBuf[ucOff++] - 0x30);

    case 1: v_ConvVal(ucBuf[ucOff++] - 0x30);

    }

    v_StartI2CandWait();  // Ausgabe auf dem SAA1064

 

    while (cValue == 0); // Warten bis Encoder gedreht wurde

    if (cValue > 0 & uiTime < (0xFFFF - RELOAD_TIME_O))

      uiTime++;

    else if (uiTime > (0xFFFF - RELOAD_TIME_U))

      uiTime--;

    cValue = 0;

  }

}

 

// ISR fuer die Takterzeugung

void v_Timer0Int(void) interrupt 1

{

  TH0 = uiTime/256;

  TL0 = (unsigned char) uiTime;

  btClk = !btClk;

}

Listing 57  Inhalt von Test_IMT901.c

Auswertung des optischen Impulsgebers (HEDS-Familie)

Optional werden die Schrittmotoren mit einem optischen 3-Kanal-Encoder ausgeliefert. Mit diesem Encoder wird überprüft, ob Schritte verloren gehen. Dies kann z. B. der Fall sein, wenn der Schrittmotor in die Eigenresonanz gerät, wenn die Taktfrequenz außer­halb des zulässigen Bereichs des Schrittmotors liegt oder wenn die Last am Motor zu groß ist. Als Impulsgeber wird der HEDL-5540 H14 von der Firma HP eingesetzt.

Erstellen sie ein Projekt, bei dem der Inkrementalgeber des Schrittmotors aus­ge­wer­tet wird. Sie können zur Vereinfachung das Projekt TestIMT901 in das neue Ver­zeichnis ko­pieren und die Dateien TestIMT901.uv2 und TestIMT901.opt um­benen­nen. Außer­dem muss unter „Options for Target“ im Reiter „Output“ der Eintrag im Feld „Name of Execu­table“ auf den Projektnamen „TestIMT901Enc“ angepasst werden.

Werten sie für den ersten Test den Nulldurchgang des Inkrementalgebers aus. Wird der Nulldurchgang erkannt, werden die Impulse des btClk gezählt. Beim nächsten Null­durch­­gang wird überprüft, ob die Anzahl der Impulse mit dem Nulldurchgang überein­stim­­men. Der Nulldurchgang soll mit dem externen Interrupt 1 ausgewertet werden. Die ISR überprüft auch die Anzahl der Impulse.

F !! Aufbau und Funktionsweise der externen Interrupts sind in Kapitel 10 [3] be­schrie­ben. !!

Projektname

Verzeichnis

Verwendete Sourcemodule

TestIMT901Enc

Test_IMT901Enc

Test_IMT901Enc.c

 

..\Library

PortConfig.c, Encoder_Lib.c, TimerLibrary.c, I2C_Lib.c, SAA1064_Lib.c

Tabelle 62  Projekt TestIMT901Enc