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?