2.4  Programmbeispiele

2.4.1  Drehimpulsgeber

Drehimpulsgeber sind eine hervorragende Möglichkeit, eine einfache aber auch multifunktionelle Benutzereingabe zu realisieren. Sie bestehen aus zwei Schaltern, die bei Rotation in unterschiedlicher Reihenfolge öffnen und schließen. Zusätzlich besitzen die meisten auch noch einen zentralen Schalter, der durch Druck auf die Achse betätigt werden kann. Bild 2.8 zeigt einen solchen Drehimpulsgeber der Firma Hopt und Schuler [Hop03].


PIC    PIC

Bild 2.8.: Drehimpulsgeber und Schaltplan


Wie zu sehen, müssen die Logikleitungen über einen Pull-Up-Widerstand an die Betriebsspannung angeschlossen werden. Bevor wir nun an die Programmierung gehen, zuerst einige Vorüberlegungen. Betrachten wir die Schaltfolge der Ausgänge in Bild 2.9 und fassen wir A und B zu einer Binärzahl zusammen, wobei B das höherwertige Bit ist, so ergibt sich für links herum drehen die Schaltfolge 00-10-11-01 und für rechts herum drehen 00-01-11-10.


PIC

Bild 2.9.: Schaltfolge des Inkrementalgebers


Die Kodierung entspricht hier einem Gray-Code, bei dem zwischen jeder Schaltstellung jeweils nur ein Bit verändert wird. Da arithmetische Operationen im Gray-Code im MSP nicht direkt gerechnet werden können, sollte vor einer weiteren Verarbeitung zuerst eine Transformation in eine binäre Darstellung erfolgen. Danach kann durch Differenzenbildung zum einen die Drehrichtung und zum anderen die Schrittweite ermittelt werden, wobei wir nur Schritte um jeweils 1 zulassen wollen. Das folgende Programmierbeispiel 2.9 zeigt nun, wie dies in konkreter Programmierung umgesetzt werden kann. Für das Verständnis der Realisierung der Umkodierung legen wir eine Wertetabelle an (Tabelle 2.4):


BA 00011110





A> 0 : wert = 1 00010100





B> 0 : wert = wert XOR 0b1100011011

Tabelle 2.4.: Wertetabelle der Umkodierung Gray-Code Binärcode

#include <msp430x14x.h> 
// Port defines. Der Drehimpulsgeber ist an Port 2 an 
// Pin 1 und Pin 2 angeschlossen 
#define INPUT_SEL      P2SEL 
#define INPUT_DIR      P2DIR 
#define INPUT_VALUE    P2IN 
#define PIN_A          BIT0 
#define PIN_B          BIT1 
 
int count = 0;                     // Globaler Zähler 
int differenz, wert, alt;          // Hilfsvariablen 
 
void main() { 
  WDTCTL=WDTPW+WDTHOLD;            // Watchdog-Timer deaktivieren 
 
  INPUT_SEL &=~(PIN_A + PIN_B);    // Konfiguration des Ports 
  INPUT_DIR &=~(PIN_A + PIN_B); 
  count = 0; 
  alt = 0; 
 
  while (1) { 
    wert =0;                       // Gray-> Binär = Dezimal 
    if ((INPUT_VALUE & PIN_A)> 0)  //  00 ->   00  =   0 
        wert = 1;                  //  01 ->   01  =   1 
    if ((INPUT_VALUE & PIN_B)> 0)  //  11 ->   10  =   2 
        wert = wert^3;             //  10 ->   11  =   3 
 
    differenz = alt-wert;          // rechts herum +1,-3 = ...01 
                                   // links herum  -1,+3 = ...11 
    if (differenz & 1)             // Bit 1 gesetzt? 
        count += (differenz & 2)-1;// Bit 2 für die Richtung 
        alt = wert;                // merke alten Wert 
} }
Listing 2.9: Ansteuerung eines Drehimpulsgebers