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-Modul) verwenden. !!
Die Firma Nanotec (www.nanotec.de) bietet den sehr leistungsfähigen Schrittmotorbaustein IMT901 an. Dieser lässt sich sehr einfach vom µController, in diesem Fall vom P89LPC932, ansteuern. Eine ausführliche Beschreibung und die notwenige Hardwarebeschaltung 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 Grenzfrequenzen sind dem Datenblatt des jeweiligen Schrittmotors 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 Reloadwert berechnet. Es wird von Betriebsart 1 eines Timers ausgegangen. In den nachfolgenden 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 enthalten. In den lokalen Variablen von main() (siehe …) werden Zwischenwerte gespeichert, 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 Variablen „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()“ erreicht (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 Konstrukt erreicht (siehe ‰). Im zweiten Konstrukt (siehe Š) erfolgt die eigentliche Ausgabe 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
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ßerhalb 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 ausgewertet wird. Sie können zur Vereinfachung das Projekt TestIMT901 in das neue Verzeichnis kopieren und die Dateien TestIMT901.uv2 und TestIMT901.opt umbenennen. Außerdem muss unter „Options for Target“ im Reiter „Output“ der Eintrag im Feld „Name of Executable“ 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 Nulldurchgang wird überprüft, ob die Anzahl der Impulse mit dem Nulldurchgang übereinstimmen. 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] beschrieben. !!
|
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