Forum: Mikrocontroller und Digitale Elektronik Drehimpulsgeber


von Gabriel (Gast)


Lesenswert?

Hi zusammen,

bin dabei einen Drehimplusgeber zu testen. Ich programmiere mit einem
Atmega32 in C. Den Drehgeber funktioniert schon zum testen... aber
möchte jetzt weiter machen aber leider habe ich noch keine ideen wie
ich mein Problem lösen könnte!
Ich möchte es so machen, dass wenn ich ein bisschen nach rechts drehe,
eine Temperatur von 30° zum bsp einstellen auf mein LCD, wenn ich dann
ein besschen weiter drehe dann 50° anzeigen, noch weiter dann 60°.....
Aber wie soll ich dass zusammen mit mein Drehimplusgeber programm
kombinieren???

Hier ist mein code zum Drehimpulsgeber:


#define PHASE_A  (!(PINA & 1<<PINA6))    // PINA.6
#define PHASE_B (!(PINA & 1<<PINA4))       // PINA.4

void Timer0_interrupt(void)
{
  static char enc_last = 0x01;
  char i = 0;

  if( PHASE_A )                             // Einlesen des Signals
    i = 1;

  if( PHASE_B )                    // Einlesen des Signals
    i ^= 3;                              // convert gray to binary

  i -= enc_last;                          // difference new - last

  if( i & 1 )                    // bit 0 = value (1)
  {
    enc_last += i;                            // store new as next last

    enc_delta += (i & 2) - 1;             // bit 1 = direction (+/-)
  }
}
 Die Ausgabe auf mein LCD mache ich mit einer lcd_ausgabe fkt!
Wäre sehr nett, wenn mir jemand weiterhilft :-)

Danke

von Christoph Kessler (db1uq) (Gast)


Lesenswert?

Ich macxhe das in Assembler so:

Ein Interruptprogramm wird von den beiden Flanken des Drehgebers
ausgelöst, und ein Register RotVal ("RotorValue") zählt von $00 aus
nach oben oder unten. Wenn $7F nach oben oder $80 nach unten erreicht
ist, zählt es nicht mehr weiter.

Das Hauptprogramm schaut periodisch nach dem Register RotVal, wenn es
Null ist, war keine Drehung. Ungleich Null: Abhängig vom oberstem Bit
war es eine Drehung links oder rechts herum. Die Änderung wird
ausgewertet und der Wert vom Hauptprogramm auf Null gestellt.

von peter dannegger (Gast)


Lesenswert?

enc_delta enthält die Änderung seit der letzten Abfrage.

Will man nun damit irgendeinen Wert ändern, muß man ihn signed addieren
und dann löschen, z.B.:
1
void aendern( int *val )
2
{
3
  cli();
4
  *val += enc_delta;
5
  enc_delta = 0;
6
  sei();
7
}


Die Interruptsperre ist notwendig, damit das Addieren und Löschen
atomar erfolgt.


Peter

von Gabriel (Gast)


Lesenswert?

Hi Peter,
kannst Du mir bitte kommentare zu dem Bsp schreiben, damit ich genauer
wissen könnte, was Du in Deinem Programm machst??
Gracia

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.