„Incremental Interface Mode“ des
Mikrocontrollers C167 von Infineon
1. Allgemeines:
Ein Timer ist ein mit Befehlen initialisierter Hardware-Zähler, der programmunabhängig läuft. Er wird vor allem für Aufgaben eingesetzt, die sich durch Software nur sehr aufwendig programmieren lassen, z.B.:
- PWM-Signal zur Ansteuerung von Motoren
- Ereigniszähler für Signalflanken
- periodische Interrupts als Zeitgeber
- Frequenzgenerator und -messer
Als Taktquelle dient der interne Prozessortakt oder ein externes Signal. Der Gate-Eingang steuert den Takt des Timers. Bei einem Nulldurchgang des Zählers wird ein Interrupt ausgelöst und kann ein Signal nach außen abgegeben werden. Hilfsregister dienen zum Nachladen, Vergleichen und Auslesen des Zählerstand es und mit Hilfe der Steuerregister können verschiedene Betriebsarten eingestellt werden, die wichtigsten sind:
- Timer-Mode: programmierbarer Frequenzteiler mit internem Takt,
- Gated Timer-Mode: Frequenzteiler mit Gate-Steuerung,
- Count-Mode: Ereigniszähler für externe Signalflanken,
- Reload-Mode: Nachladbare Frequenzteiler,
- Capture-Mode: Auslesen des Zählerstandes bei einem bestimmten Ereignis,
- Compare-Mode: Ausgabe eines Signals bei einem bestimmten Zählerstand,
- Incremental Interface-Mode: Erfassen phasenverschobener Positionssignale.
Es ist allerdings zu beachten, dass nicht jede Betriebsart von jedem Timer unterstützt wird.
2. Mehrzweck-Timereinheiten:
Die Mehrzweck-Timereinheiten (General Purpose Timer) GPT1 (Abb. 1) und GPT2 des Mikrocontrollers C167 arbeiten völlig unabhängig voneinander und setzen sich aus 3 (GPT1) bzw. 2 (GPT2) 16-Bit Einzelzählern zusammen, wobei jeweils einer der Hauptzähler ist (Core Timer). Jeder dieser 5 Timer kann entweder für sich alleine oder in Kombination (z.B. kaskadiert) betrieben werden. Die Auflösung reicht je nach Einstellung und Timer von 160 ns bis ca. 41 µs, die maximale Periode liegt damit zwischen 10 ms und 2,68 s (alle Werte bei 25 MHz Taktfrequenz).
Über die externen Steuereingänge TxEUD kann die Zählrichtung der Timer verändert werden. Welcher Pegel hier welche Zählrichtung einstellt, ist zudem wählbar, so dass eine Anpassung an die verschiedensten Einsatzbedingungen möglich ist. Die interne Hardware der Timer ist so aufgebaut, dass bei jedem Zählimpuls, sei er vom internen Takt abgeleitet oder durch eine Flanke am externen Zähleingang TxIN erzeugt, gleichzeitig der Zustand der Zählrichtungseinstellung überprüft und der Timer dann entsprechend inkrementiert oder dekrementiert wird. Insbesondere im Counter-Betrieb mit externer Richtungseinstellung werden die beiden Eingänge TxIN und TxEUD zum selben Zeitpunkt abgefragt. Liegt kein Zählimpuls vor, hat der Zustand der Richtungseinstellung keine Bedeutung.
Abbildung 1: General Purpose Timer Unit GPT1
3. Erfassen phasenverschobener Positionssignale:
Diese gleichzeitige Abfrage der Richtungseingänge lässt sich gut ausnutzen, um phasenverschobene Signale, wie sie durch Wegstrecken-Sensoren oder ähnliches erzeugt werden, zu verarbeiten.
Abbildung 2: Generierung phasenverschobener Positionssignale
Abb. 2 zeigt die Generierung solcher Signale über z.B. eine spezielle Skala mit gegeneinander verschobenen Schwarz/Weiß-Balken, die mit optischen Sensoren abgetastet wird. Durch die Phasenverschiebung steckt in den beiden Signalen der Sensoren nicht nur die Zählinformation (also z.B. das Wegstrecken-Inkrement), sondern auch eine Richtungsinformation. Kommt die steigende Flanke von Signal 1 vor der steigenden Flanke von Signal 2, bedeutet dies z.B. die Richtung Rechts. Dreht sich die Richtung der Bewegung um, so kommt diesmal die steigende Flanke von 1 nach der steigenden Flanke von Signal 2. Wie kann nun diese Information mit einem Timer verarbeitet werden?
Variante 1 (Count-Mode):
Die beiden Signale sind ja auf den ersten Blick nicht trennbar in ein Zählsignal, das an den Count-Eingang TxIN anzuschließen wäre, und ein Richtungssignal, das den Eingang TxEUD steuert. Es ist jedoch einfach und ohne zusätzliche externe Gatter möglich, diese beiden Signale korrekt zu verarbeiten, allerdings mit der Einschränkung der geringeren Frequenz. Die Lösung des Problems liegt in der oben beschriebenen Tatsache, dass die Richtungsinformation am Pin TxEUD nur dann benötigt wird, wenn ein Zählimpuls anliegt. Schließt man nun Signal 1 an den Count-Eingang TxIN an und programmiert den Timer im Zählerbetrieb so, dass er z.B. die positive Flanke des Signals zählt, so kann man aus Abb. 3 sehen, dass der momentane Zustand des Signals 2 zum Zeitpunkt der positiven Flanke von Signal 1 die Richtungsinformation wiedergibt.
Abbildung 3: Bewertung des Richtungseingangs nur bei positiver Zählflanke
Man kann also Signal 2 direkt an den Steuereingang TxEUD legen und erhält so die gewünschte Funktion ohne zusätzlichen Aufwand. Abb. 4 zeigt den Verlauf des Zählerstandes für verschiedene Bewegungsrichtungen.
Abbildung 4: Zählerstand bei verschiedenen Bewegungsrichtungen
Allerdings arbeitet diese Lösung nur mit einer geringeren Frequenz im Vergleich zu speziellen ASIC-Bausteinen für diesen Zweck (Quadratur-Zähler). Bei dieser Methode wird ja nur eine Flanke von einem der beiden Signale als Zähl-Inkrement benutzt, während es mit zusätzlichem Logik-Aufwand möglich ist, jede Flanke beider Signale auszuwerten und so eine zwei- oder vierfach höhere Zählfrequenz zu erreichen (= höhere Genauigkeit).
Variante 2 (Incremental Interface-Mode):
Der Mehrzweck-Timer GPT1 stellt diesen zusätzlichen Logik-Aufwand in Form des „Incremental Interface-Mode“ zur Verfügung. Dabei kann der Eingang TxEUD nicht nur für die Richtungsinformation, sondern auch zur Flankenzählung verwendet werden.
Weiters besteht nun die Möglichkeit, sowohl steigende als auch fallende Flanken mit entsprechender Richtung zu zählen. Somit erreicht man eine bis zu vierfach höhere Zählfrequenz gegenüber Variante 1. Die anschließenden Erklärungen beziehen sich immer auf Timer T2, sie gelten aber genauso für die beiden anderen Timer von GPT1 (Timer 1 und 3).
Folgende Register gehören zu T2:
T2: Timer Datenregister: Dieses Register enthält den aktuellen Zählerwert. Je nach Drehrichtung des Signalgebers wird der Wert erhöht oder verringert.
T2IC: Interrupt Control Register:
Beim Überlauf des Timerregisters T2 von FFFFH auf 0000H (Aufwärtszählen) bzw. 0000H auf FFFFH (Abwärtszählen) wird ein Interrupt ausgelöst und T2IR gesetzt. Sind gleichzeitig das Einzel-Freigabebit T2IE = 1 und das Gesamt-Freigabebit IEN=1, so liegt die Anforderung an der Interrupt-Steuerung an und es wird die passende Interrupt Service Routine aufgerufen. Die Bitfelder ILVL und GLVL legen die Interrupt-Prioritätsebene fest.
Die neuen 16bit Mikrocontroller der Serie XC16x von Infineon [2] bieten eine Erweiterung, die bei jeder Flanke aber auch bei einem Richtungswechsel einen Interrupt auslöst. Das Control Register enthält drei zusätzliche Flags für die aktuelle Richtung, Richtungswechsel- und Flankenerkennung.
T2CON: Control Register: Zum Setzen des Modus und Konfiguration des Timers.
Tabelle 1 und 2 erklärt die Bedeutung der einzelnen Bitfelder und Bits.
Bit |
Funktion |
T2I |
Timer 2 Input Selection: abhängig von Modus T2M (siehe Tabelle 4) |
T2M |
Timer 2 Mode Control: 000: Timer Mode 001: Counter Mode 010: Gated Timer mit Gate active low 011: Gated Timer mit Gate active high 100: Reload Mode 101: Capture Mode 110: Incremental Interface Mode 111: Reserviert. Nicht verwenden. |
T2R |
Timer 2 Run Bit: 0: Timer 2 deaktiviert 1: Timer 2 aktiviert |
T2UD |
Timer 2 Up/Down Control: Siehe Tabelle 2 |
T2UDE |
Timer 2 External Up/Down Enable: Siehe Tabelle 2 |
Tabelle 1: Timer 2 Control Register Bits
Pin T2EUD |
Bit T2UDE |
Bit T2UD |
Zählrichtung |
X |
0 |
0 |
Aufwärts |
X |
0 |
1 |
Abwärts |
0 |
1 |
0 |
Aufwärts |
1 |
1 |
0 |
Abwärts |
0 |
1 |
1 |
Abwärts |
1 |
1 |
1 |
Aufwärts |
Tabelle 2: Timer 2 Zählrichtungskontrolle
Um den Incremental Interface-Mode ausführen zu können, müssen folgende Bedingungen erfüllt sein:
- Bitfeld T2M muss auf #110b gesetzt sein.
- Beide Pins (T2IN und T2EUD) müssen auf Input geschaltet sein, d.h. die entsprechenden Direction Control Bits sind #0b.
- Bit T3UDE muss #1b sein, damit die automatische Richtungskontrolle aktiviert wird. Tabelle 3 zeigt die daraus resultierenden Richtungskombinationen.
Level des entsprechend anderen Eingangs |
T2IN Eingangsflanke |
T2EUD Eingangsflanke |
||
Steigend |
Fallend |
Steigend |
Fallend |
|
High |
Abwärts |
Aufwärts |
Aufwärts |
Abwärts |
Low |
Aufwärts |
Abwärts |
Abwärts |
Aufwärts |
Tabelle 3: Automatische Zählrichtungen bei Incremental Interface-Mode
Wie oben bereits erwähnt, kann in diesem Modus die Zählfrequenz variiert werden. Tabelle 4 zeigt die möglichen Einstellungen und Abb. 5 bzw. 6 passende Beispiele.
T2I |
Funktion |
000 |
Keine. Zähler T2 stoppt. |
001 |
Bei jeder Flanke an T2IN zählen. |
010 |
Bei jeder Flanke an T2EUD zählen. |
011 |
Bei jeder Flanke an T2IN und T2EUD zählen. |
1xx |
Reserviert. Nicht verwenden. |
Tabelle 4: Timer 2 Input Selection T2I bei Incremental Interface-Mode
Abbildung 5: Timer zählt bei jeder Veränderung von Eingang T2IN
Abbildung 6: Timer zählt bei jeder Veränderung von Eingang T2IN und T2EUD
4. Beispiel:
Der Timer T2 soll benutzt werden, um die zwei Ausgangssignale eines magnetischen Impulsgebers zu dekodieren. Diese sind an den I/O-Pins T2IN und T2EUD des C167 angeschlossen. Damit ergibt sich folgende Einstellung für T2CON (#0173h):
Programm Code:
Im folgenden Programmteil werden die Drehzahlen zweier Antriebsmotoren eines Roboters über die Ausgänge magnetischer Signalgeber gemessen. Dazu wird Timer 2 und 4 der Einheit GPT1 verwendet. Die Einstellungen zu Timer 4 erfolgen analog zu Timer 2 (siehe oben). Die Funktion „increm_initialize“ bereitet die notwendigen Register vor, „increm_update“ aktualisiert die Geschwindigkeiten „v_outL“ und „v_outR“ des linken bzw. rechten Rades. Die Funktion muss regelmäßig aufgerufen werden (in diesem Fall jede Millisekunde) um einen Timerüberlauf zu verhindern. Aus Performance-Gründen wurde der Programm-Code in Assembler geschrieben:
Datei „increm_f.A66”:
;/*****************************************************************************/
;/* ROBY-RUN - SUPERROBOT */
;/* MOTION UNIT: INCREMENTAL DECODER */
;/* */
;/* (c) 2003 by Bernhard Putz */
;/*****************************************************************************/
$NOMACRO
$SEGMENTED CASE MOD167
$MODINF (43)
NAME INCREM_F
; Used registers:
P3 DEFR 0FFC4H
DP3 DEFR 0FFC6H
P5 DEFR 0FFA2H
T4 DEFR 0FE44H
T2 DEFR 0FE40H
T4IC DEFR 0FF64H
T2IC DEFR 0FF60H
T4CON DEFR 0FF44H
T2CON DEFR 0FF40H
ASSUME DPP3 : SYSTEM
; global variables:
EXTRN DPP3 : v_outL : WORD
EXTRN DPP3 : increm_counterL : WORD
EXTRN DPP3 : v_outR : WORD
EXTRN DPP3 : increm_counterR : WORD
REGDEF R0 - R15
?PR?INCREM_F SECTION CODE WORD 'NCODE'
;/*****************************************************************************/
;/* INCREM_INITIALIZE */
;/* Initializes the Incremental Decoders for measuring velocities */
;/*****************************************************************************/
increm_initialize PROC NEAR
PUBLIC increm_initialize
; increm_counterL = 0x8000; // middle position
MOV R4,#32768
MOV WORD increm_counterL,R4
; increm_counterR = 0x8000; // middle position
MOV WORD increm_counterR,R4
; // Set Ports for Input and 0
; P3 &= 0xFF7F; // P3.7 = T2IN
AND P3,#65407
; DP3 &= 0xFF7F; // P3.7 = T2IN as input
AND DP3,#65407
; P5 &= 0x7FFF; // P5.15 = T2EUD
AND P5,#32767
; P3 &= 0xFFDF; // P3.5 = T4IN;
AND P3,#65503
; DP3 &= 0xFFDF; // P3.5 = T4IN as input
AND DP3,#65503
; P5 &= 0xBFFF // P5.14 = T4EUD
AND P5,#49151
; // Set GPT 2 and 4 for Incremental Mode
; T2=0x8000; // Reset Timer values in middle position
MOV T2,#32768
; T4=0x8000; // Reset Timer values in middle position
MOV T4,#32768
; T2CON=0x0173; // Incremental Mode
MOV T2CON,#371
; T4CON=0x0173; // Incremental Mode
MOV T4CON,#371
; T2IC=0x0000; // Set Interrupt Control Register (no interrupts !)
MOV T2IC,#0
; T4IC=0x0000; // Set Interrupt Control Register (no interrupts !)
MOV T4IC,#0
RET
increm_initialize ENDP
?PR?INCREM_F ENDS
?PR?FASTCODE SECTION CODE WORD PUBLIC 'XRAM'
;/*****************************************************************************/
;/* INCREM_UPDATE */
;/* Stores incremental inputs to counter variables and updates v_outL/R */
;/*****************************************************************************/
increm_update PROC NEAR
PUBLIC increm_update
; Save Timer values:
ATOMIC #2
MOV R9,T2
MOV R8,T4
; // Fast Encoder to Velocity (E2V) calculation:
; // E2V_MF = GEAR_FACTOR * DIAMETER_WHEEL * PI /
; ENCODER_RESOLUTION / CONTROL_INTERVAL * 1000 * 2^E2V_SF
; #define E2V_MF 8595L // multiplication factor
; #define E2V_SF 10 // shift factor
; v_outL = (E2V_MF * (increm_counterL - t4)) >> E2V_SF;
; Shift number in R3:
MOV R3,#10
MOV R5,WORD increm_counterL
SUB R5,R8
MOV R4,#8595
MUL R5,R4
MOV R5,MDH
MOV R4,MDL
MOV R6,R5
ASHR R5,R3
SHR R4,R3
NEG R3
SHL R6,R3
OR R4,R6
MOV WORD v_outL,R4
; v_outR = (E2V_MF * (increm_counterR - t2)) >> E2V_SF;
; Shift number in R3:
MOV R3,#10
MOV R5,WORD increm_counterR
SUB R5,R9
MOV R4,#8595
MUL R5,R4
MOV R5,MDH
MOV R4,MDL
MOV R6,R5
ASHR R5,R3
SHR R4,R3
NEG R3
SHL R6,R3
OR R4,R6
MOV WORD v_outR,R4
; save last counter values
MOV WORD increm_counterL,R8
MOV WORD increm_counterR,R9
RET
increm_update ENDP
?PR?FASTCODE ENDS
END
5. Anwendung und Tests:
Die Funktionalität der Enkoder Unit wurde anhand einer Motorsteuerung getestet. Im vorliegenden Testfall wurde die Drehzahl zweier über ein PWM Signal angesteuerte DC Motoren geregelt. Als Referenzwert dienten die Impulse der direkt an den DC Motoren angebrachten digitalen 2-Kanal Enkoder. Dieser Enkoder lieferte pro Umdrehung 512 Impule auf 2 Kanälen. Die im C167er implementierte Enkoder Unit ist in der Lage diesen Wert intern zu vervierfachen, wodurch sich 2048 Impulsen pro Umdrehung ergaben. Als Testboard wurde das von Gregor Novak und Christian Perschl entwickelte ub167 verwendet. Das ub167 ist eine komplette, kostengünstige Plattform für einfache und komplexe Aufgaben der Steuerungs-, Regelungs- und Messtechnik. Zur Plattform gehört neben der universellen Hardware auch das Softwarekonzept: vorkonfigurierte Musterprojekte, Softwaremodule in C-Source und das Tool Minimon für Download und Test. Das Gehirn von ub167 ist ein 16-Bit Mikrocontroller der Firma Infineon, der C167CR, welcher mit 20 MHz getaktet wird (10 MIPS Rechenleistung). Er enthält einen 10 Bit A/D Wandler mit 16 Kanälen und 9.7µs Wandlungszeit, eine leistungsfähige CAN Bus Schnittstelle, eine asynchrone und eine schnelle synchrone serielle Schnittstelle, eine 4-Kanal PWM Einheit, mehr als 70 freikonfigurierbare digitale Ein-/Ausgänge, 9 Timer und vieles mehr. All diese Peripherie ist in Silicon und kann ohne zusätzliche Hardware verwendet werden. Nähere Information und die Bezugsquelle des ub167 findet sich unter www.bluetechnix.at/ub167.
6. Literatur:
- C167CR Derivatives User’s Manual v3.1, Infineon Technologies AG, 2000
- XC161 User’s Manual v2.0 – Peripheral Units, Infineon Technologies AG, 2003
- MC-Tools 17 – Arbeiten mit C166-Controllern, Karl-Heinz Mattheis / Steffen Storandt, 1995
- Mikrocomputertechnik mit dem Controller C167, Günter Schmitt, 2000
- Einsatz von Mikrocontrollern in der Robotertechnik, Christian Perschl, 2000