Drehencoder mit Atmega644

OP #1422370
Lesenswert?
• ▲
▼
Hallo, ich wollte einen Drehencoder (ALPS E12D mit Taster) mithilfe der 
Routinen von PeDa ansteuern.

Leider komme ich nicht weiter. Da ich einen Atmega644 verwende, habe ich 
die Timer-Routine angeändert:
1
void encode_init( void )
2
{
3
  int8_t new;
4
 
5
  new = 0;
6
  if( PHASE_A )
7
    new = 3;
8
  if( PHASE_B )
9
    new ^= 1;          // convert gray to binary
10
  last = new;          // power on state
11
  enc_delta = 0;
12
  TCCR0B = 1<<WGM01;
13
  ^1<<CS01^1<<CS00;    // CTC, XTAL / 64
14
  OCR0B = (uint8_t)(F_CPU / 64.0 * 1e-3 - 0.5);  // 1ms  // F_CPU = 22.1Mhz
15
  TIMSK0 |= 1<<OCIE0B;
16
}
17
 
18
 
19
ISR( TIMER0_COMPA_vect )        // 1ms for manual movement
20
{
21
  int8_t new, diff;
22
 
23
  new = 0;
24
  if( PHASE_A )
25
    new = 3;
26
  if( PHASE_B )
27
    new ^= 1;          // convert gray to binary
28
  diff = last - new;        // difference last - new
29
  if( diff & 1 ){        // bit 0 = value (1)
30
    last = new;          // store new as next last
31
    enc_delta += (diff & 2) - 1;    // bit 1 = direction (+/-)
32
  }
33
}

Aber ich bekomme keine Ausgaben. Ich vermute mal, dass mein Timer-Gedöns 
nicht stimmt.

Den Encoder habe ich mit PinA an PHASE_A(=PC3) und PinB an PHASE_B(=PC4) 
angeschlossen. PinC=GND und PinE=VCC. PinD=PC2 (Taster). Stimmt die 
Beschaltung?
#1422607
Lesenswert?
• ▲
▼
1
  TCCR0B = 1<<WGM01;
2
  ^1<<CS01^1<<CS00;    // CTC, XTAL / 64

Falls das deine Aenderungen der Timer-Routine (?) sind, dann wuerde ich 
in der Tat sagen, dass es daran liegt.

Laut http://www.atmel.com/dyn/resources/prod_documents/doc2593.pdf 
(Seite 100) ist bei CS02=CS01=CS00=0 keine clock source gewaehlt, der 
Timer somit inaktiv. Das ist bei dir der Fall, da du keines der 
entsprechenden bits in TCCR0B setzt.
OP #1423637
Lesenswert?
• ▲
▼
Hier ein neuer Versuch. Timer0 wird benutzt mit Prescaler 1024. Sollte 
doch für das Compare-register bei 1ms etwa 21,59 ergeben.
1
*********
2
encode_init();
3

4
sei();
5
for(;;){
6
    val += encode_read1();      // read a single step encoder
7
    LED_TESTPORT = (1 << val);
8

9
  sprintf(buffer,"Ausgabe: %li\n", val);
10
  uart_puts(buffer);
11

12
  _delay_ms(100);
13
  LED_TESTPORT &= ~(1<<LED_ERRPIN); //löschen
14
  }
15
**************
16
void encode_init( void )
17
{
18
  int8_t new;
19
 
20
  new = 0;
21
  if( PHASE_A )
22
    new = 3;
23
  if( PHASE_B )
24
    new ^= 1;          // convert gray to binary
25
  last = new;          // power on state
26
  enc_delta = 0;
27

28
  // Timer0 initialisieren
29
  
30
  //WGM01=1: CTC Mode
31
  TCCR0A = (0<<COM1A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (0<<WGM00);
32
  //CS=101 = prescaler 1024
33
  TCCR0B = (0<<FOC0A) | (0<<FOC0B) | (1<<WGM02) | (1<<CS12) | (0<<CS11) | (1<<CS10); 
34
  // Compare register
35
  OCR0A = F_CPU/1024/1000;         //je 1ms (sollte bei 22.11Mhz etwa 21.59 ergeben
36
  // Intterupt maskieren auf OCR0A
37
  TIMSK0 |= (1<<OCIE0A);
38
}
39
 
40
 
41
ISR( TIMER0_COMPA_vect )        // 1ms for manual movement
42
{
43
  int8_t new, diff;
44
 
45
  new = 0;
46
  if( PHASE_A )
47
    new = 3;
48
  if( PHASE_B )
49
    new ^= 1;          // convert gray to binary
50
  diff = last - new;        // difference last - new
51
  if( diff & 1 ){        // bit 0 = value (1)
52
    last = new;          // store new as next last
53
    enc_delta += (diff & 2) - 1;    // bit 1 = direction (+/-)
54
  }
55
}

In der Ausgabe (RS232) sehe ich manchmal eine -1 und manchmal eine 0 
durchlaufen. Es sieht so aus, als ob eine Richtung angezeigt wird.
Ist der Anschluss des Drehencoders korrekt?

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