mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Dreahimpulsgeber auswertung


Autor: Ephraim Hahn (ephi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin gerade etwas am verzeifeln mit meinem Drehencoder.
Es handelt sich um den STEC12 von reichelt (ALPS).

Ich versuche mich mit Peter Dannegers routinen aus dem Artikel.

Hier meine Umsetzung:
// rotary encoder header
#define ENC_PORT    PORTC
#define ENC_DDR      DDRC
#define ENC_PIN      PINC
#define ENC_A      6
#define ENC_B      7
#define PHASE_A      (ENC_PIN & 1<<PC6)
#define PHASE_B      (ENC_PIN & 1<<PC7)

// abschnitt der init routine
ENC_DDR &= ~(1<<ENC_A) | ~(1<<ENC_B);  // rotary encoder pins as inout
ENC_PORT |= (1<<ENC_A) | (1<<ENC_B);  // pull ups on
  
uint8_t new = 0;
if(PHASE_A)
  new = 3;
if(PHASE_B)
  new ^= 1;
last = new;
enc_delta = 0;

TCCR1B = (1<<WGM12) | (1<<CS12) | (1<<CS10);  // CTC Mode, F_CPU/1024
OCR1A = (uint16_t)(F_CPU / 1024 * 1e-3 - 0.5);  // 1ms
TIMSK1 = (1<<OCIE1A);        // enable timer interrupt


// ISR
ISR(TIMER1_COMPA_vect)
{  
  int8_t new = 0, diff;
  
  if(PHASE_A)
    new = 3;
  if(PHASE_B)
    new ^= 1;            // convert gray to binary
  diff = last - new;          // difference last - new
  if(diff & 1)
  {                  // bit 0 = value (1)
    last = new;            // store new as next last
    enc_delta += (diff & 2) - 1;  // bit 1 = direction (+/-)
  }
  
  // 7 segment multiplexing
  switch(tr)
  {
    case 0:
      PORT_TRANS |= (1<<TRANS_4);
      PORT_DISP = digit[1];
      PORT_TRANS &= ~(1<<TRANS_1);
      tr = 1;
      break;
    case 1:
      PORT_TRANS |= (1<<TRANS_1);
      PORT_DISP = digit[0];
      PORT_TRANS &= ~(1<<TRANS_2);
      tr = 2;
      break;
    case 2:
      PORT_TRANS |= (1<<TRANS_2);
      PORT_DISP = digit[2];
      PORT_TRANS &= ~(1<<TRANS_3);
      tr = 3;
      break;
    case 3:
      PORT_TRANS |= (1<<TRANS_3);
      PORT_DISP = digit[3];
      PORT_TRANS &= ~(1<<TRANS_4);
      tr = 0;
      break;
  }
}

// regelmäßige Abfrage in der Hauptschleife:
tmr = (uint8_t)encode_read1();

Hab es auch schon mit encode_read2 und 4 versucht.
tmr bleibt immer 0.

Eigentlich möchte ich mit dem encoder in tmr nur einen wert von 0...30 
einstellen können. geht das irgendwie auch einfacher?

Es handelt sich um einen ATMega644p mit 16Mhz externem Quarz.


Kann mir jemand helfen?

Autor: Boris H. (eddi)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Bei mir sieht das Ganze für eine Lampensteuerung mit PWM so aus.
Einstellbar ist der Wert pwm von 0 bis enc_end

Autor: Ephraim Hahn (ephi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
okay, nach deiner Methode funktionierts, danke!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ephraim Hahn schrieb:
> Hab es auch schon mit encode_read2 und 4 versucht.
> tmr bleibt immer 0.

Das Problem ist, daß der GCC in den Standardeinstellungen kleine 
Funktinen inlined und dann muß man enc_delta als volatile definieren, 
sonst wird das neu lesen wegoptimiert.


Peter

Autor: Ephraim Hahn (ephi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
enc_delta war bei mir aber volatile (hab die definitionen vergessen zu 
posten)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.