Hallo und einen schön Abend,
ich habe hier einen Drehencoder von Reichelt und zwar ist es der ALPS
STEC12E08, das Datenblatt habe ich angehangen. Ich versuche ihn den
ganzen Tag schon zum laufen zubringen doch er möchte leider nicht so
ganz.
Das Tutorial hier http://www.mikrocontroller.net/articles/Drehgeber,
habe ich auch schon durchgelesen und das angepasste Programm auf mein µc
geladen doch leider ohne Erfolg. Dort wird der Drehencoder ja ohne
Interrupt ausgelesen, allerdings passiert nicht mal ansatzweise etwas
wenn ich den Encoder drehe.
So wie ich das in sämtlichen Beiträgen raus gelesen habe, ist es ein
Encoder mit wackeligen Rastpunkt, sieht man auch ganz gut im Datenblatt,
ferner in den Zustandsdiagrammen. Somit sollte ja wenn auf Phase A, eine
steigende auf INT0 Flanke reinkommt ein Interrupt ausgelöst werden und
in dem kann ich dann die Phase B auswerten, und eine Variable entweder
inkrementieren oder dekrementieren. Soweit so gut, ein bisschen
funktioniert mein Programm auch, allerdings nur ein bisschen :( Wenn ich
den Encoder drehe wird meine Variable ständig inkrementiert, allerdings
völlig willkürlich, entweder um 2 oder 3 oder 4, wobei ich denke das es
vom prellen des Encoders kommt.
Hier mal mein Programm dazu. Hoffe ihr könnt mir etwas helfen da ich
echt nicht weiter komme. Noch ein paar Infos dazu: Takt 8Mhz,
Rn-Control, Display angeschlossen 1x16 Char. Den Encoder habe ich wie im
Datenblatt angeschlossen mit den beiden Pull-ups.
1 |
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 | #include <stdlib.h>
|
5 | #include "lcd.h"
|
6 | #include <avr/pgmspace.h>
|
7 | #include <util/delay.h>
|
8 |
|
9 | volatile uint8_t val = 50; //globale Variable für Drehencoder
|
10 |
|
11 |
|
12 |
|
13 | ISR (INT0_vect) { //Interruptroutine
|
14 | if (!(PORTD & (1 << PIND3))) //Phase B auswerten, wenn von Phase A eine
|
15 | val++; //steigende Flanke ausgeht, wird Phase B ausgewertet,
|
16 | else //ist dann Phase B negativ ist die Drehrichtung C.W.
|
17 | val--; //und umgekehrt, sprich Phase B postiv, Drehrichtung C.C.W.
|
18 | PIND &= ~ (1 << PIND3);
|
19 | }
|
20 |
|
21 |
|
22 | void timer_init (void) { //Timer0 auf Int0 initialisieren
|
23 | MCUCR |= (1 << ISC01) | (1 << ISC00); //steigende Flanke
|
24 | GICR |= (1 << INT0);
|
25 | sei(); //Globale Interrupts ein
|
26 | }
|
27 |
|
28 |
|
29 | int main (void) {
|
30 | DDRD &=~ (1 << PIND2)| (1 << PIND3); //Eingäne definieren
|
31 |
|
32 | DDRB |= (1 << PB6); //Displaybeleuchtung ein
|
33 | PORTB |= (1 << PB6);
|
34 |
|
35 | uint8_t help;
|
36 | char value [10];
|
37 |
|
38 | help = val;
|
39 |
|
40 |
|
41 | timer_init (); //Timerinitialisierung
|
42 |
|
43 | lcd_init(LCD_DISP_ON); //LCD Initialisierung
|
44 | lcd_clrscr ();
|
45 |
|
46 | lcd_puts ("Drehencoder"); //Displayanzeige
|
47 | _delay_ms (300);
|
48 | lcd_clrscr ();
|
49 |
|
50 | itoa (val, value, 10); //Typenumwandlung von Integer in char
|
51 | lcd_puts (value);
|
52 |
|
53 |
|
54 |
|
55 |
|
56 | while (1) {
|
57 |
|
58 |
|
59 | if (help != val) { //Variable vom Drehencoder auf dem Display darstellen
|
60 | lcd_clrscr (); //welche nur bei Bedarf aktuallisiert wird
|
61 | itoa (val, value, 10);
|
62 | lcd_puts (value);
|
63 | help = val;
|
64 |
|
65 | }
|
66 |
|
67 | }
|
68 |
|
69 | }
|
Vielen Dank schonmal im Vorraus :)