1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 |
|
4 | #define XTAL 16000000 // Frequenz des Arduino
|
5 | #define Phase_A (PINB & 1<<PB0) // PIN8 als Pin1 des Drehencoders
|
6 | #define Phase_B (PINB & 1<<PB1) // PIN9 als Pin2 des Drehencoders
|
7 |
|
8 | byte tflags = 0x00; // Übersicht der Eingangssignale (Global)
|
9 | byte jflags = 0x00; // Übersicht der zu erledigen Jobs (Global)
|
10 | byte sflags = 0x00; // Übersicht der verschiedenen Stati (Global)
|
11 |
|
12 | volatile int8_t enc_delta; // Variable zur Speicherung der Encoder Richtung (Global)
|
13 | static int8_t last; // Variable zur Speicherung des letzten Encoder Wertes (Global)
|
14 |
|
15 | ISR(TIMER2_COMPA_Vect) // Interrupt Service Routine Timer2
|
16 | {
|
17 | int8_t neu = 0, diff;
|
18 | if(Phase_A)
|
19 | {
|
20 | neu = 3;
|
21 | PORTB ^= (1<<PB2); //Testausgang toggeln, Anzeige PinA
|
22 | }
|
23 | if(Phase_B)
|
24 | {
|
25 | neu ^= 1;
|
26 | PORTB ^= (1<<PB3); //Testausgang toggeln, Anzeige PinB
|
27 | }
|
28 | diff = last - neu;
|
29 | if(diff & 1) // prüfen ob ein Schritt vom Encoder aufgelaufen ist
|
30 | { // wenn eine Änderung aufgelaufen ist
|
31 | last = neu; // neuen Encoderzustand speichern
|
32 | enc_delta += (diff & 2) -1; // Drehrichtung bestimmen und enc_delta anpassen
|
33 | }
|
34 | }
|
35 | int8_t encoder_einlesen(void) // Funktion zum periodischen Einlesen der Encoderschritte
|
36 | {
|
37 | int8_t val;
|
38 |
|
39 | cli(); // globale Interruptfreigabe sperren
|
40 | val = enc_delta;
|
41 | enc_delta = 0; // Schrittänderung an die main-Funktion zurückgeben
|
42 | sei(); // globele Interruptfreigabe setzen
|
43 | return val; // Inhalt von val an die main Funktion zurückgeben
|
44 | }
|
45 |
|
46 |
|
47 | void setup()
|
48 | {
|
49 | Serial.begin(9600);
|
50 | /*
|
51 | // I/O Pins initialisieren
|
52 | DDRB = 0x0C; // PORTB Pins als Input
|
53 |
|
54 | // Timer1 als PWM initialisieren
|
55 | TCCR1A |= (1<<WGM11) | (1<<WGM10); // CTC Modus
|
56 | TCCR1B |= (1<<WGM12) | (1<<WGM13) | (1<<CS11); // Prescaler auf 8
|
57 | TIMSK1 |= (1<<OCIE1A); // Interrupt für CTC-A aktivieren
|
58 | OCR0A = 84; // Wert der verglichen werden soll (24kHz)
|
59 | ICS1 = 84;
|
60 | */
|
61 |
|
62 | // Timer2 initialisieren
|
63 | TCCR2A |= (1<<WGM21); // CTC Modus
|
64 | TCCR2B |= (1<<CS22); // Prescaler auf 64
|
65 | //TIMSK2 |= (1<<OCIE2A); // Interrupt für CTC-A aktivieren
|
66 | OCR2A = 0xFF; // Wert der verglichen werden soll (1ms)(250)
|
67 |
|
68 | //Encoder Variablen initialisieren
|
69 | int8_t neu = 0;
|
70 | if(Phase_A)
|
71 | {
|
72 | neu = 3;
|
73 | }
|
74 | if(Phase_B)
|
75 | {
|
76 | neu ^= 1; // neu Xor verknüpfen
|
77 | }
|
78 |
|
79 | sei(); // globele Interruptfreigabe setzen
|
80 |
|
81 | }
|
82 |
|
83 | void loop()
|
84 | {
|
85 | int32_t val = 0;
|
86 | Serial.println(val);
|
87 |
|
88 | while(true)
|
89 | {
|
90 | val += encoder_einlesen(); // Geänderte Schrittzahl zu val addieren
|
91 |
|
92 | }
|
93 |
|
94 | }
|