www.mikrocontroller.net

Forum: Compiler & IDEs Drehgeber auf Atmega 88 wandeln


Autor: Tom St. (sticksi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Forenmitglieder!

Ich wollte etwas mit einem Drehgeber experimentieren. Arbeite mit dem 
STK 500 und einem Atmega 88. Der Drehgeber kommt von ALPS

http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=B29...

Nun wollte ich das Programm aus dem Wiki 
http://www.mikrocontroller.net/articles/Drehgeber

durchführen.

Hab entsprechende Änderungen im Programm durchgeführt, aber es klappt 
noch nichts.
#include <avr/io.h>
#include <avr/interrupt.h>
#define XTAL        8000000         // 8MHz
#define PHASE_A     (PIND & 1<<PD1)
#define PHASE_B     (PIND & 1<<PD3)
#define LEDS_DDR    DDRC
#define LEDS        PORTC           // LEDs against VCC
 
volatile int8_t enc_delta;          // -128 ... 127
static int8_t last;
 
void encode_init( void )
{
  int8_t neu;
 
  neu = 0;
  if( PHASE_A )
    neu = 3;
  if( PHASE_B )
    neu ^= 1;                   // convert gray to binary
  last = neu;                   // power on state
  enc_delta = 0;
  TCCR1B = 1<<WGM12^1<<CS11^1<<CS10;     // CTC, XTAL / 64
  OCR1BL = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5);   // 1ms
  TIMSK1 |= 1<<OCIE1B;
}
 
ISR( TIM1_COMPB_vect )             // 1ms for manual movement
{
  int8_t neu, diff;
 
  neu = 0;
  if( PHASE_A )
    neu = 3;
  if( PHASE_B )
    neu ^= 1;                   // convert gray to binary
  diff = last - neu;                // difference last - new
  if( diff & 1 ){               // bit 0 = value (1)
    last = neu;                 // store new as next last
    enc_delta += (diff & 2) - 1;        // bit 1 = direction (+/-)
  }
}

int8_t encode_read2( void )         // read two step encoders
{
  int8_t val;
 
  cli();
  val = enc_delta;
  enc_delta = val & 1;
  sei();
  return val >> 1;
}
 
 int main( void )
{
  int32_t val = 0;
 
  LEDS_DDR = 0xFF;
  encode_init();
  sei();
 
  for(;;){
    val += encode_read2();          // read a single step encoder
    LEDS = val;
  }
} 

Kompilieren ist o.k. Aber keine Anzeige. Denke ich habe einen 2 step 
encoder. Wollte mit dem Drehgeber später einmal einfach ein Register 
hoch und runterzählen.

Wo liegt der Fehler?

Vielen Dank im voraus

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pull-ups?

Oliver

Autor: Tom St. (sticksi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Pullups habe ich fest verdrahtet auf dem Lochraster. Mit 10k an 5V. Habe 
alternativ auch schon mal mit den Tastern vom STK 500 probiert. doch es 
wurde überhaupt nichts angezeigt. alle Leds sind an, also Speicherinhalt 
= 0.

Dacht erst ich hätte den Counter falsch initialisiert, aber das müsste 
eigentlich passen......

Autor: Tom St. (sticksi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat vielleicht noch jemand eine Idee?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schreib mal ne Mainloop: PORTC = PIND und dreh mal langsam, ob die 4 
Phasen zu sehen sind.


Peter

Autor: Tom St. (sticksi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jupp, das funktioniert. Led links rechts bzw rechts links sind am 
blinken. Aber das Programm scheint irgendwie keine Eingänge zu bekommen 
oder zählt einfacch nichts. Hab leider kein Dragon Modul zum debuggen.

Sind denn meine Änderungen am Counter für den Atmega 88 richtig?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom St. schrieb:
> Jupp, das funktioniert. Led links rechts bzw rechts links sind am
> blinken.

Ja, aber auch richtig?
D.h. alle 4 Phasen sind zu sehen?

Der Code sieht o.k. aus, häng mal Dein .lss File ran.


Peter

Autor: Tom St. (sticksi)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Also ich habe 2 LEDs die ich ansteuer. Wenn ich links herum drehe, kommt 
erst die linke und dann kurz darauf die rechte LED (ähnlich 
Wechselblinker). Wenn ich rechts herum drehe, kommt erst die rechte LED 
und kurz darauf die linke. Hab gerade noch gesehen, das mir AVR beim 
übersetzen eine Warnung auspuckt:

../Drehgeber.c:28: warning: 'TIM1_COMPB_vect' appears to be a misspelled 
signal handler

Macht vielleicht der Compiler probleme?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom St. schrieb:
> Also ich habe 2 LEDs die ich ansteuer. Wenn ich links herum drehe, kommt
> erst die linke und dann kurz darauf die rechte LED (ähnlich
> Wechselblinker). Wenn ich rechts herum drehe, kommt erst die rechte LED
> und kurz darauf die linke. Hab gerade noch gesehen, das mir AVR beim
> übersetzen eine Warnung auspuckt:
>
> ../Drehgeber.c:28: warning: 'TIM1_COMPB_vect' appears to be a misspelled
> signal handler
>
> Macht vielleicht der Compiler probleme?


TIMER1_COMPB_vect

Autor: Tom St. (sticksi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe ich geändert. War auf TIM weilch das so im Handbuch für Atmega88 
stand. Jetzt ist zumindest die Warnung weg, aber immernoch kein zählen. 
Wenn ich anstelle der Pins 1 & 3 nun 4 & 3 ändern möchte, dann mach ich 
das zum einem oben beim `define´ und auch unten bei ´neu´ ,oder?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom St. schrieb:
> Habe ich geändert.

Und, wird sie auch aufgerufen?

(In der ISR zur Kontrolle eine LED einschalten)

Autor: Tom St. (sticksi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LED bekomme ich in der ISR nicht zum leuchten. Er scheint eine Abfrage 
der Eingänge zu machen, im encode_init. Dann geht er in main und 
arbeitet die for-Schleife ab. Fragt wohl die Eingänge nicht mehr ab. Der 
Vergleich in der ISR findet wohl nicht statt. Komm irgendwie nicht 
weiter.....  bitte um weitere Vorschläge  DANKE!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom St. schrieb:
> TCCR1B = 1<<WGM12^1<<CS11^1<<CS10;     // CTC, XTAL / 64
>   OCR1BL = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5);   // 1ms

Sicher, daß diese Zeile auch das macht und daß CTC bei Compare-B 
erfolgt?


Peter

Autor: Tom St. (sticksi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, habe jetzt beide Handbücher (dauert etwas zu laden), Atmega16

http://www.atmel.com/dyn/resources/prod_documents/...

und das vom Atmega88

http://www.atmel.com/dyn/resources/prod_documents/...

genau verglichen. Damit ich die gleichen Funktionen wie auf dem 16er 
nutzen kann, muss ich beim 88er den Timer/Counter1B benutzen. 
Entsprechende Änderungen habe ich im Programm vorgenommen.

 TCCR1B = 1<<WGM12^1<<CS11^1<<CS10;     // CTC, XTAL / 64
  OCR1B = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5);   // 1ms
  TIMSK1 |= 1<<OCIE1B;
}

ISR(TIMER1_COMPB_vect)             // 1ms for manual movement
{
  int8_t neu, diff;
     ;
  neu = 0;
.....

Aber, wie sollte es anders sein, immernoch keine Zählung.

Bin jetzt am Ende meiner Ideen. Wieso kann ich den 88er nicht zum laufen 
bekommen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom St. schrieb:

> genau verglichen. Damit ich die gleichen Funktionen wie auf dem 16er
> nutzen kann, muss ich beim 88er den Timer/Counter1B benutzen.

ALso ich les da was anderes aus dem 88-er Datenblatt

Tabelle 15.4
Modus 4, CTC

Der Top Wert ist OCR1A

A nicht B

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ...

  OCR1BL = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5);   // 1ms

nur dann eben mit A und nicht B, würde ich auch nicht so machen.
Wer sagt dir, dass da kein Wert größer 255 rauskommt

   OCRA1 = XTAL / 64.0 * 1e-3 - 0.5;

Autor: Tom St. (sticksi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SUPER! Das wars!

Nur jetzt muss ich das erstmal verstehen. Ihr sagtet das ich OCRA1A 
nehmen soll. Mit dem gehts auch. Nur laut Handbuch hat das 
TCCR1A-Register keine Möglichkeit das WGM12 - Bit zu setzen, welches ja 
laut Tabelle 15-4 erfordelich ist um CTC zu setzen. Deswegen bin ich auf 
das TCCR1B gegangen. Hier kann ich das Register auf CTC setzen, sowie 
auch den erfordelichen Teiler (64) einstellen. Wo war mein Denkfehler?

Vielen Dank für Eure Hilfe !!!

Tom

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom St. schrieb:

> Nur jetzt muss ich das erstmal verstehen. Ihr sagtet das ich OCRA1A
> nehmen soll. Mit dem gehts auch.

Gut

> Nur laut Handbuch hat das
> TCCR1A-Register keine Möglichkeit das WGM12 - Bit zu setzen,


richtig

> welches ja
> laut Tabelle 15-4 erfordelich ist um CTC zu setzen.

Das Bit ist im TCCR1B Register

> Deswegen bin ich auf
> das TCCR1B gegangen. Hier kann ich das Register auf CTC setzen, sowie
> auch den erfordelichen Teiler (64) einstellen. Wo war mein Denkfehler?

TCCR1A ist nicht gleich OCRA1

Das eine ist das KOnfigurationsregister und das andere ist das 
Vergleichsregister.

Und auch ja: TCCR1A hat nicht deswegen ein A am Ende, weil es das 
Konfigurationsregister für den A Kanal ist. Es gibt einfach 2 Stück 
Konfigurationsregister, TCCR1A und TCCR1B die beide zusammen Dinge am 
Timer 1 einstellen.
Das hat aber nichts mit einem A Kanal oder einem B Kanal zu tun, so wie 
beim OCRA1. Da steht ja auch das A vor der Zahl (die den Timer 
symbolisiert) und nicht dahinter :-)


Sorgfältig arbeiten und nicht übereilt Schussfolgern. Im Zweifel nicht 
raten, sondern im Datenblatt nachsehen.

Autor: Tom St. (sticksi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
O.k. das macht Sinn.

zitat:
Das hat aber nichts mit einem A Kanal oder einem B Kanal zu tun, so wie
beim OCRA1. Da steht ja auch das A vor der Zahl und nicht dahinter?


Nur in meinem Handbuch steht überall OCR1A und wenn ich das mal anders 
in den Compiler tippe, dann gibts auch einen error:

../Drehgeber.c:24: error: 'OCRA1' undeclared (first use in this 
function)

Trotzdem schon mal vielen Dank für die Erklärung, Karl Heinz !

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom St. schrieb:
> O.k. das macht Sinn.
>
> zitat:
> Das hat aber nichts mit einem A Kanal oder einem B Kanal zu tun, so wie
> beim OCRA1. Da steht ja auch das A vor der Zahl und nicht dahinter?
>
>
> Nur in meinem Handbuch steht überall OCR1A und wenn ich das mal anders
> in den Compiler tippe, dann gibts auch einen error:

Erwischt.

Nehm mich schon selber an der Nase und schau demnächst wieder mehr ins 
Datenblatt für die Bezeichnungen :-)

Autor: Falk Brunner (falk)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs mal damit . . .

Autor: Marc Höner (bauerpilot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ihr,
ich stehe gerade am Anfang der Programmierung und versuche mit ein Bild 
zu machen und die Programme nachzuvollziehen.
Gibt es irgendwo eine detailierte Doku, was die Befehle im einzelnen 
bedeuten, gerade die C-Befehle? Z.B. "+=", "^=" oder "&".
Wahrscheinlich werden die meisten von Euch jetzt lachen, aber jeder hat 
doch mal angefangen.
Ich habe es mittlerweile geschafft den Drehgebercode auf einen Attiny 
2313 zu portieren und alles läuft bestens.
Mein Ziel ist es den Code soweit zu verändern, dass ich zwei Drehgeber 
anschliesse und die Ausgabe für jeden Drehgeber nur angibt ob links oder 
rechts gedreht wurde. Für jeden Detent/Raste ein kurzes Signal am 
Ausgang (ca. 2ms).
Kann mir jemand helfen?

Gruß Marc

Autor: Axel Düsendieb (axel_jeromin) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc Höner schrieb:
> Gibt es irgendwo eine detailierte Doku, was die Befehle im einzelnen
> bedeuten, gerade die C-Befehle? Z.B. "+=", "^=" oder "&".
>


AVR-GCC-Tutorial


> Mein Ziel ist es den Code soweit zu verändern, dass ich zwei Drehgeber
> anschliesse und die Ausgabe für jeden Drehgeber nur angibt ob links oder
> rechts gedreht wurde. Für jeden Detent/Raste ein kurzes Signal am
> Ausgang (ca. 2ms).
> Kann mir jemand helfen?

Da brauchst Du das obige Programm nicht, da reicht eine einfache 
Flankenbildung

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc Höner schrieb:

> Gibt es irgendwo eine detailierte Doku, was die Befehle im einzelnen
> bedeuten, gerade die C-Befehle? Z.B. "+=", "^=" oder "&".

Das steht in jedem C-Buch.
Das AVR-GCC-Tutorial ist da weniger hilfreich, da es bereits von 
gewissen Grundkenntnissen in C ausgeht.

Du brauchst ein C-Buch!

> Wahrscheinlich werden die meisten von Euch jetzt lachen, aber jeder hat
> doch mal angefangen.

Schon. Haben wir. Auch uns ist das alles nicht in die Wiege gelegt 
worden.
Wir haben Bücher durchgearbeitet. Denn da steht erst mal alles drinn, 
was C ausmacht. Wir haben auf dem PC geübt. Bis die Finger gekracht 
haben. Bis wir in C geträumt haben. Und nachdem der Grundstock in C da 
war, haben wir noch den µC-spezifischen Teil durchgearbeitet. Zb mit dem 
AVR-GCC-Tutorial.

Autor: Marc Höner (bauerpilot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besten Dank für die Infos, dann muss ich mir wohl ein entsprechendes 
Buch zulegen. Gibt es da besondere Empfehlungen?
Gruß Marc

Autor: Marc Höner (bauerpilot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir ist ja mittlerweile viel klar geworden, habe eine Menge im net 
gelesen.
Eine Frage aber bleibt noch.
Was bedeutet: "return val >> 1;" am Ende der Funktion? Wird die Variable 
"val" mit um ein Bit nach rechts verschobenen werten ausgegeben, oder 
wie?
Mein Ziel ist es immer noch den Code so anzupassen, dass die Ausgabe nur 
anzeigt, ob rechts oder links gedreht wurde.
@Axel: Mir ist klar, dass das auch einfacher geht, aber ich möchte üben 
und verstehen.
Vielleicht kann mir ja doch jemand helfen.
Wenn ich es richtig verstehe der der Wert von "encode_read2()" die 
Anzahl der counts seit dem letzten Aufruf an und das ganze mit 
Vorzeichen.
Wenn ich jetzt die Schleife wie folgt ändere:
  for(;;){
    val = encode_read2();
    LEDS = val;
  }
müsste ich doch eigentlich die Anzahl der counts mit Vorzeichen 
angezeigt bekommen? Leider passiert bei mir nichts.

Gruß Marc

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc Höner schrieb:
> Mir ist ja mittlerweile viel klar geworden, habe eine Menge im net
> gelesen.
> Eine Frage aber bleibt noch.
> Was bedeutet: "return val >> 1;" am Ende der Funktion? Wird die Variable
> "val" mit um ein Bit nach rechts verschobenen werten ausgegeben, oder
> wie?

Ganz genau.
Ist eine Division konzeptionell eine Division durch 2.

> Mein Ziel ist es immer noch den Code so anzupassen, dass die Ausgabe nur
> anzeigt, ob rechts oder links gedreht wurde.

Ja, dann mach das doch.
Wenn das was du aus encode_read2() bekommst positiv ist, dann wurde nach 
rechts gedreht. Ist es negativ, dann nach links.

> Wenn ich es richtig verstehe der der Wert von "encode_read2()" die
> Anzahl der counts seit dem letzten Aufruf an und das ganze mit
> Vorzeichen.

ganz genau

> Wenn ich jetzt die Schleife wie folgt ändere:
>   for(;;){
>     val = encode_read2();
>     LEDS = val;
>   }
> müsste ich doch eigentlich die Anzahl der counts mit Vorzeichen
> angezeigt bekommen? Leider passiert bei mir nichts.

So schnell wirst du nicht schauen können.
Denn im Vergleich dazu, wie schnell der µC feststellt dass der Encoder 
nicht gedreht wurde und daher alle LED wieder abschaltet, ist das Drehen 
des Encoders ein seltenes/wahnsinnig schnell vorbeigehendes Ereignis. 
Dein encode_read2 wird dir 99.9999% der Zeit melden, dass sich nichts 
getan hat. Und genau das siehst du auch an den LED - nämlich nichts.

Warum lässt du dir denn nicht die Encoderpulse aufsummieren, wie Falk 
das in seiner Vorlage gezeigt hat? Dann zählen die LED mit jedem Drehen 
binär entsprechend hoch/runter.

Autor: Steven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ohne mir jetzt deinen Code oder den Threadverlauf genau durchgelesen zu 
haben wollte ich nur kurz anmerken, dass der Drehgeber, für den ich vor 
kurzer Zeit eine Auswertungsroutine geschrieben habe (Bourns PEC12) 
anders als hier im entsprechenden Wiki-Eintrag auf dem ersten Diagramm 
zu erkennen bei "Raststellungen" jeweils keinen Durchgang hat. Es ist 
also nur jeder zweite der im Diagramm zu sehenden Rastpunkte auch 
tatsächlich vorhanden.
Ich vermute, dass sich dies von Encoder zu Encoder unterscheidet.

MfG

Steven

Autor: Marc Höner (bauerpilot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt habe ich meinen gedanklichen Fehler gefunden. Danke dafür Karl 
Heinz.
Der Änderungsimpuls (+/-) ist natürlich sehr kurz und kann optisch nicht 
erkannt werden.
Wieder etwas mehr Verständniss erlangt.
Die Vorlage von Falk läuft ausgezeichnet, das war mein erstes 
Erfolgserlebnis.
Jetzt geht es mir darum die Drehung des Enkoders an einen 
Tastaturemulator anzuschliessen, dafür brauche ich nur die Signale ob 
links oder rechts gedreht wird und dann für jeden klick ein Signal.

Autor: Marc Höner (bauerpilot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ihr,
ich bin immer noch am grübeln und probieren komme aber nicht richtig 
weiter.
Die Funktion encoder_read2() gibt die Anzahl der counts mit Vorzeichen 
an, das Karl Heinz bestätigt. Daraus folgt: ein detent nach rechts = +1, 
ein detent nach links = -1.
Wesentlich für die Ausgabe ist die "for Schleife" am Ende des 
main-Programms.
Diese habe ich mal zu Testzwecken wie folgt geändert:

  for(;;){
     LEDS = encode_read2();
    if (LEDS != 0)
      _delay_ms(100);
    val += encode_read2();          // read a two step encoder

  }

Nach meinem Verständnis wird jetzt bei einem drehen um eine Raste nach 
links oder rechts die if-Bedingung erfüllt und das Programm für 100ms 
angehalten und die Anzeige zeigt +/-1 an, je nach Drerichtung.
Das funktioniert aber leider nicht zuverlässig, mal kommt die Anzeige, 
mal nicht. Kann jemand helfen?
Mir ist klar, das die delay-Funktion nicht sehr elegant ist oder stört 
sie sogar hier? Eigentlich möchte ich die Anzeige über eine 
timer-function steuern , damit das Programm nicht angehalten wird. Aber 
soweit bin ich noch nicht.
Gruß Marc

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marc Höner schrieb:

>   for(;;){
>      LEDS = encode_read2();
>     if (LEDS != 0)
>       _delay_ms(100);
>     val += encode_read2();          // read a two step encoder
>
>   }

du darfst encode_read2 nur EINMAL aufrufen!

> Das funktioniert aber leider nicht zuverlässig, mal kommt die Anzeige,
> mal nicht. Kann jemand helfen?

Logisch. Weil beim 2.ten Aufruf von encode_read2 unter Umständen genau 
die Drehung zurückgegeben würde, mit der du dann aber nichts machst!

Autor: Marc Höner (bauerpilot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besten Dank. Jetzt funktioniert dieser Teil schon einmal.
Aber meine Fragen gehen weiter. Ich habe eine zusätzliche Variable 
eingeführt, es sieht jetzt so aus:
 int main( void )
{

  int8_t richt;

  PORTD = 0xFF;
  DDRD = 0x00;
  LEDS_DDR = 0xFF;
  encode_init();
  sei();

  for(;;){
    richt = encode_read2();
    if (richt != 0){
     _delay_ms(50);
    }
  }
}
Nichts geht mehr, was habe ich jetzt schon wieder falsch gemacht?

Autor: Marc Höner (bauerpilot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleine Korrektur, so sieht der Code aus:
  ...
  int8_t richt;
  PORTD = 0xFF;
  DDRD = 0x00;
  LEDS_DDR = 0xFF;
  encode_init();
  sei();

  for(;;){
    richt = encode_read2();
    if (richt != 0){
     LEDS = richt;
     _delay_ms(50);
    }
  }
}
...

Autor: Marc Höner (bauerpilot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur noch eine kurze Erläterung:
Ziel ist es den Wert von encode_read2 einer Variablen zuzuweisen. Diese 
Variable soll dann geprüft werden. Ist der Wert > 0, dann LEDS = 0x01, 
ist der Wert < 0 dann LEDS = 0x02.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Marc Höner (bauerpilot)

  int8_t richt, cnt;
  PORTD = 0xFF;
  DDRD = 0x00;
  LEDS_DDR = 0xFF;
  encode_init();
  sei();

  for(;;){
    richt = encode_read2();
    if (richt > 0) {
      LEDS = 0x01;
      cnt = 50;
    }
    else if (richt<0) {
      LEDS = 0x02;
      cnt = 50;
    }
    if (cnt >0) cnt--;
    if (cnt == 0) LED = 0;
    _delay_ms(1);
  }

Autor: Marc Höner (bauerpilot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besten Dank, werde ich gleich ausprobieren.

Autor: Marc Höner (bauerpilot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Falk,
besten Dank nochmal, der Code funktioniert ausgezeichnet.
Hallo Alle,
Da ich ja mittlerweile gelernt habe, das delays nicht besonders elegant 
sind, würde ich das ganze gerne über den timer steuern.
Wie genau muss ich das realisieren?
Im Prinzip müsste ich eine globale Variable (mit volatile) definieren, 
die bei jedem Aufruf der ISR inkrementiert wird. Abfrage in der 
for-Schleife im main-Programm. Wenn die gewünschte Zeit (x ms) 
überschritten ist, ausschalten der Ausgänge. Jetzt geht es noch um das 
zurücksetzen, damit bei einer erneuten Eingabe die Ausgänge wieder 
geschalten werden. Wo muss das geschehen, in "encoder_read"?
Gruß Marc

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.