Dreahimpulsgeber auswertung

OP #1462819
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:
1
// rotary encoder header
2
#define ENC_PORT    PORTC
3
#define ENC_DDR      DDRC
4
#define ENC_PIN      PINC
5
#define ENC_A      6
6
#define ENC_B      7
7
#define PHASE_A      (ENC_PIN & 1<<PC6)
8
#define PHASE_B      (ENC_PIN & 1<<PC7)
9

10
// abschnitt der init routine
11
ENC_DDR &= ~(1<<ENC_A) | ~(1<<ENC_B);  // rotary encoder pins as inout
12
ENC_PORT |= (1<<ENC_A) | (1<<ENC_B);  // pull ups on
13
  
14
uint8_t new = 0;
15
if(PHASE_A)
16
  new = 3;
17
if(PHASE_B)
18
  new ^= 1;
19
last = new;
20
enc_delta = 0;
21

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

26

27
// ISR
28
ISR(TIMER1_COMPA_vect)
29
{  
30
  int8_t new = 0, diff;
31
  
32
  if(PHASE_A)
33
    new = 3;
34
  if(PHASE_B)
35
    new ^= 1;            // convert gray to binary
36
  diff = last - new;          // difference last - new
37
  if(diff & 1)
38
  {                  // bit 0 = value (1)
39
    last = new;            // store new as next last
40
    enc_delta += (diff & 2) - 1;  // bit 1 = direction (+/-)
41
  }
42
  
43
  // 7 segment multiplexing
44
  switch(tr)
45
  {
46
    case 0:
47
      PORT_TRANS |= (1<<TRANS_4);
48
      PORT_DISP = digit[1];
49
      PORT_TRANS &= ~(1<<TRANS_1);
50
      tr = 1;
51
      break;
52
    case 1:
53
      PORT_TRANS |= (1<<TRANS_1);
54
      PORT_DISP = digit[0];
55
      PORT_TRANS &= ~(1<<TRANS_2);
56
      tr = 2;
57
      break;
58
    case 2:
59
      PORT_TRANS |= (1<<TRANS_2);
60
      PORT_DISP = digit[2];
61
      PORT_TRANS &= ~(1<<TRANS_3);
62
      tr = 3;
63
      break;
64
    case 3:
65
      PORT_TRANS |= (1<<TRANS_3);
66
      PORT_DISP = digit[3];
67
      PORT_TRANS &= ~(1<<TRANS_4);
68
      tr = 0;
69
      break;
70
  }
71
}
72

73
// regelmäßige Abfrage in der Hauptschleife:
74
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?
#1463264
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.