Hab hier schnell mal was für einen zweiphasigen Drehencoder
zusammengebastelt.
Gilt für Drehencoder mit folgender Sequenz 00->01->11->00
1 | #include <util/delay.h>
|
2 | #include <avr/io.h>
|
3 | #define PHASE_A (PINC & 1<<PA0)
|
4 | #define PHASE_B (PINC & 1<<PA1)
|
5 | #define ROTARY_ENC (1<<0) | (1<<1)
|
6 |
|
7 |
|
8 | void wait(uint16_t ms){
|
9 | while(ms){
|
10 | ms--;
|
11 | _delay_ms(1);
|
12 | }
|
13 | }
|
14 |
|
15 | uint8_t rotary(void)
|
16 | {
|
17 | static uint8_t gray_old = 0;
|
18 | uint8_t gray;
|
19 | uint8_t ret;
|
20 |
|
21 | ///Hier sollte eine richtige Timerroutine eingebaut werden
|
22 | wait(1);
|
23 |
|
24 | //Graycode Umrechnen
|
25 | gray = 0;
|
26 | if( PHASE_A )
|
27 | gray = 3;
|
28 | if( PHASE_B )
|
29 | gray ^= 1;
|
30 |
|
31 | //Ist die Diff -1 oder 2 -> Drehung nach rechts
|
32 | //Ist die Diff 1 oder -2 -> Drehung nach links
|
33 | //Ist die Diff 0 -> Keine Drehung
|
34 | switch(gray_old - gray)
|
35 | {
|
36 | case -1:ret = 1;break;
|
37 | case 2:ret = 1;break;
|
38 | case 1:ret = 2;break;
|
39 | case -2:ret = 2;break;
|
40 | case 0:ret = 0;break;
|
41 | }
|
42 | gray_old = gray;
|
43 | //1 bedeutet rechts
|
44 | //2 bedeutet links
|
45 | //0 bedeutet keine Drehung
|
46 | return ret;
|
47 | }
|
48 |
|
49 |
|
50 | main()
|
51 |
|
52 | //Pullups
|
53 | PORTC |= (1<<PA0) | (1<<PA1);
|
54 | uint8_t richtung;
|
55 | //Einmalig aufrufen um Werte zu initialisieren
|
56 | rotary();
|
57 |
|
58 | while(1)
|
59 | {
|
60 | richtung = rotary();
|
61 | }
|
62 | }
|
Es ist nicht gerade der sauberste Stil, aber wer es brauchen kann, soll
es benutzen.