Dreahimpulsgeber auswertung

OP #1462819
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:
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
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren