mikrocontroller.net

Forum: Compiler & IDEs Drehcoder ALPS Stec12E08 will nicht


Autor: Mücke (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.
 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include "lcd.h"
#include <avr/pgmspace.h>
#include <util/delay.h>

volatile uint8_t val = 50;     //globale Variable für Drehencoder



ISR (INT0_vect) {              //Interruptroutine
  if (!(PORTD & (1 << PIND3))) //Phase B auswerten, wenn von Phase A eine 
    val++;                     //steigende Flanke ausgeht, wird Phase B ausgewertet,
  else                //ist dann Phase B negativ ist die Drehrichtung C.W.
    val--;                //und umgekehrt, sprich Phase B postiv, Drehrichtung C.C.W.
  PIND &= ~ (1 << PIND3);
}


void timer_init (void) {                 //Timer0 auf Int0 initialisieren
  MCUCR |= (1 << ISC01) | (1 << ISC00);  //steigende Flanke
  GICR |= (1 << INT0);
  sei();                                 //Globale Interrupts ein
  }


int main (void) {
  DDRD &=~ (1 << PIND2)| (1 << PIND3);   //Eingäne definieren

  DDRB  |= (1 << PB6);                   //Displaybeleuchtung ein 
  PORTB |= (1 << PB6);

  uint8_t help;              
  char value [10];

  help = val;


  timer_init ();                         //Timerinitialisierung

  lcd_init(LCD_DISP_ON);                 //LCD Initialisierung 
  lcd_clrscr ();

  lcd_puts ("Drehencoder");              //Displayanzeige
  _delay_ms (300);
  lcd_clrscr ();

  itoa (val, value, 10);              //Typenumwandlung von Integer in char
  lcd_puts (value);




  while (1) {


    if (help != val) {          //Variable vom Drehencoder auf dem Display darstellen
      lcd_clrscr ();            //welche nur bei Bedarf aktuallisiert wird
      itoa (val, value, 10);
      lcd_puts (value);
      help = val;

    }

  }

}

Vielen Dank schonmal im Vorraus :)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Mücke (Gast)

>Das Tutorial hier http://www.mikrocontroller.net/articles/Drehgeber,
>habe ich auch schon durchgelesen

Aber scheinbar nicht verstanden. :-(

>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.

Tj, du bist auch mal wieder oberschlau. Mach es wie im Tutorial mit 
einem Timer-Interrupt und gut. Deine External Interrupt Sache ist Müll!

>ferner in den Zustandsdiagrammen. Somit sollte ja wenn auf Phase A, eine
>steigende auf INT0 Flanke reinkommt ein Interrupt ausgelöst werden und

NEIN! LIES DEN VERDAMMTEN ARTIKEL!

Autor: Mücke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann sein das ich es nicht verstanden habe, deswegen wohl auch der 
Beitrag. Aber trotzdem danke für deine Mühe und Hilfe, ich werds nochmal 
lesen : )

Autor: Mücke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal,

und zwar habe ich mir das Tutorial noch einmal zu gemühte geführt und 
siehe da es funktioniert und zwar tadellos :-) Jetzt habe ich auch den 
Code verstanden^^

Allerdings hat sich, so denke ich, in dem Tutorial ein kleiner aber 
entscheidender Fehler eingeschlichen. Und zwar bei der Initialisierung 
in dem Program mit dem wackeligen Rastpunkt.
int main( void )
{
  int32_t val = 0;
 
  LEDS_DDR = 0xFF;      <<<--Hier fehlt die Funktion encode_init ()
  sei();
 
  while(1){
    val += encode_read();      
    LEDS = val;
  }
}

Ohne die Init klappt es bei mir jedenfalls nicht.

Einen schönen Abend noch :-)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Mücke (Gast)

>und zwar habe ich mir das Tutorial noch einmal zu gemühte geführt und
>siehe da es funktioniert und zwar tadellos :-)

Surprise, Surprise . . .

>Jetzt habe ich auch den Code verstanden^^

Na immerhin.

>Allerdings hat sich, so denke ich, in dem Tutorial ein kleiner aber
>entscheidender Fehler eingeschlichen. Und zwar bei der Initialisierung
>in dem Program mit dem wackeligen Rastpunkt.

Ja, ist ein Fehler. Danke für die Mitteilung. Hab ich korrigiert.

MFG
Falk

Autor: Frank Buss (foobar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst es übrigens auch interruptbasiert programmieren, aber wichtig 
dabei ist, nicht auf einen flankenwechsel den Interrupt auszulösen, 
sondern per Timerinterrupt, wie ich es hier implementiert habe:

http://www.frank-buss.de/attiny/index.html

Prellen ist egal bei Quadraturencodern, solange der Interrupt schneller 
ist, als der Abstand zwischen zwei Rasterpositionen bei schnellster 
Drehung.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.