Forum: Analoge Elektronik und Schaltungstechnik Frage zu Artikel Drehgeberauswertung


von Ralf (Gast)


Lesenswert?

Hallo,
 ich habe eine Frage zu dem folgenden Artikel über die Auswertung von 
Drehgebern: http://www.mikrocontroller.net/articles/Drehgeber

In der Erklärung des soliden Codes steht der Satz “…allerdings handelt 
man sich die Unschönheit ein, dass man im entsprechenden Makro auf eine 
interne Variable der Auswertefunktion zugreift. (Als „saubere“ 
Alternative müsste man den Code so umschreiben, dass das Erfassen der 
Werte und die Auswertung der gewünschten Spur in separate 
inline-Funktionen getrennt werden.)“

Wurde der Beispielcode nachträglich noch angepasst, oder sehe ich das 
Problem einfach nur nicht? Es wird doch ausschließlich in der 
Auswertefunktion auf die Variable zugegriffen.

1
ISR( TIMER0_COMP_vect )             // 1ms for manual movement
2
{
3
  int8_t new, diff;
4
  uint8_t encoderpin = PINA;
5
        
6
  if(encoderpin & 1<<PA1)
7
    new = 3;
8
  if(encoderpin & 1<<PA3)
9
    new ^= 1;    
10
11
  // …
12
}

von guest (Gast)


Lesenswert?

Ralf schrieb:
> Wurde der Beispielcode nachträglich noch angepasst, oder sehe ich das
> Problem einfach nur nicht? Es wird doch ausschließlich in der
> Auswertefunktion auf die Variable zugegriffen.
>
> ISR( TIMER0_COMP_vect )             // 1ms for manual movement
> {
>   int8_t new, diff;
>   uint8_t encoderpin = PINA;
>
>   if(encoderpin & 1<<PA1)
>     new = 3;
>   if(encoderpin & 1<<PA3)
>     new ^= 1;
>
>   // …
> }

Tja, wenn Du aus dem Originalcode die fragllichen Makros 
wegrationalisierst, kannst Du das Problem natürlich nicht mehr sehen.
Gemeint sind hier die Makros PHASE_A und PHASE_B. Die funktionieren halt 
nur, wenn es in den Funktionen, in denen sie benutzt werden auch eine 
lokale Variable encoderpin gibt.

1
#define PHASE_A     (encoderpin & 1<<PA1)
2
#define PHASE_B     (encoderpin & 1<<PA3)
3
#define PIN_ENCODER PINA
4
5
void encode_init( void )
6
{
7
  int8_t new;
8
  uint8_t encoderpin = PIN_ENCODER;
9
10
  new = 0;
11
  if( PHASE_A )
12
    new = 3;
13
  if( PHASE_B )
14
    new ^= 1;                   // convert gray to binary
15
  last = new;                   // power on state
16
  enc_delta = 0;
17
  TCCR0 = 1<<WGM01^1<<CS01^1<<CS00;     // CTC, XTAL / 64
18
  OCR0 = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5);   // 1ms
19
  TIMSK |= 1<<OCIE0;
20
}
21
 
22
 
23
ISR( TIMER0_COMP_vect )             // 1ms for manual movement
24
{
25
  int8_t new, diff;
26
  uint8_t encoderpin = PIN_ENCODER;
27
28
  new = 0;
29
  if( PHASE_A )
30
    new = 3;
31
  if( PHASE_B )
32
    new ^= 1;                   // convert gray to binary
33
  diff = last - new;                // difference last - new
34
  if( diff & 1 ){               // bit 0 = value (1)
35
    last = new;                 // store new as next last
36
    enc_delta += (diff & 2) - 1;        // bit 1 = direction (+/-)
37
  }
38
}

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.