Forum: Mikrocontroller und Digitale Elektronik Problem: ATMega88 mit Encoder


von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe ein Problem mit dem Einlesen eines Encoders (Pollin: PANASONIC 
EVEQDBRL416B).

Hardware: ATMega88
Programm: Anlehnung an Beispiel unter 
http://www.mikrocontroller.net/articles/Drehgeber (s. Anhang)

Bei der Problemsuche sind mir folgende Punkte aufgefallen:

OCR2A = (uint8_t)(XTAL2 / 64.0 * 1e-3 - 0.5)
Das Register sollte doch mit einem Wert gefüllt werden, der jede 
Millisekunde einen Interrupt erzeugt - oder? Bei meinem Programm stimmte 
dies nicht. Wie kommt man auf diese Formel?

Ich habe daraufhin folgenden Fix-Wert angegeben:
OCR2A = (uint8_t)(15);  // 1ms
Begründung: Die interne Clock-Frequenz ist 1/8 der Systemclock. Mit 
einem Vorteiler von 64 benötigt man somit 64us bis zum nächsten Zählwert 
im Timer. Nach 15*64us hat man rund 1ms (mit Oszi nachgemessen).

Das Hauptproblem sind aber die Berechnungen der Variablen "diff" und 
"enc_delta" in der Interruptroutine.

Die Reihenfolge der Variable "new" in die 1. Drehrichtung ist nach 
meiner Meinung 0->1->2->3->0 usw. und in die andere 0->3->2->1->0. Die 
Differenz ist somit -1 bzw. +1. (Ausnahme: 3->0 bzw. 0->3).

An dieser Stelle bin ich dann "ausgestiegen". Kann mir daher bitte 
jemand die Zeilen von

diff = last - new;                // difference last - new
  if( diff & 1 ){               // bit 0 = value (1)
    last = new;                 // store new as next last
    enc_delta += (diff & 2) - 1;        // bit 1 = direction (+/-)
  }

erklären?

von muha (Gast)


Lesenswert?

>OCR2A = (uint8_t)(XTAL2 / 64.0 * 1e-3 - 0.5)
>Das Register sollte doch mit einem Wert gefüllt werden, der jede
>Millisekunde einen Interrupt erzeugt - oder? Bei meinem Programm stimmte
>dies nicht. Wie kommt man auf diese Formel?

>Ich habe daraufhin folgenden Fix-Wert angegeben:
>OCR2A = (uint8_t)(15);  // 1ms
>Begründung: Die interne Clock-Frequenz ist 1/8 der Systemclock. Mit
>einem Vorteiler von 64 benötigt man somit 64us bis zum nächsten Zählwert
>im Timer. Nach 15*64us hat man rund 1ms (mit Oszi nachgemessen).

Du stellst eine Frage um sie Dir dann selber zu beantworten.
Übrigens, sieht deine Rechnung gut aus.

Gruß JOnas

von Falk B. (falk)


Lesenswert?

@ Thomas (Gast)

>An dieser Stelle bin ich dann "ausgestiegen". Kann mir daher bitte
>jemand die Zeilen von

Das ist die Peter Dannneger'sche Ultrakompaktschreibweise ;-)
Es ist im Wesentlichen ein Umcodierung von Cray Code auf Binärcode.
Am Besten kann man es nachvollziehen, wenn man die mal alle Codetabellen 
aufschreibt.

von Thomas (Gast)


Lesenswert?

Ich "hänge" leider immer noch....

Die Bedingung if (diff & 1) ist erfüllt, wenn die Variable "diff" den 
Wert "1" besitzt. Was ist aber wenn die Variable "diff" den Wert "-1" 
besitzt?

Mit der Formel  enc_delta += (diff & 2) - 1 kann ich überhaupt nichts 
anfangen....

von Falk B. (falk)


Lesenswert?

@ Thomas (Gast)

>Die Bedingung if (diff & 1) ist erfüllt, wenn die Variable "diff" den
>Wert "1" besitzt.

Nein. Wenn die bitweise Verknüpfung von diff und der Konstanten 1 
logisch wahr ist. Sprich, wenn das LSB von diff gesetzt ist. Siehe 
Bitmanipulation.

> Was ist aber wenn die Variable "diff" den Wert "-1"
> besitzt?

-1 = 0xFF -> ebenso wahr ;-)

>Mit der Formel  enc_delta += (diff & 2) - 1 kann ich überhaupt nichts
>anfangen....

Siehe oben. Du musst erstmal die C-Grundlagen lernen, damit du die 
Befehle richtg verstehst. DANN kannst du über den Algorithmus 
nachdenken.

enc_delta += (diff & 2) - 1
enc_delta  = enc_delta + (diff & 2) - 1

(diff & 2) -> bitweise Verknüpfung von diff und 2

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.