mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C-Codeverbesserung für PS/2 Maus Abfrage.


Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nabend, ich hab mal eine Frage zur Mausabfrage mit einem ATMega:

Ich lese die PS/2 Maus gemäß 
http://www.computer-engineering.org/ps2mouse/ aus.

Bekomme also 3 Byte.

1. Enthält die Überlauf, Vorzeichenbits und Button Bits.
2. Enthält die x Bewegung.
3. Enthält die y Bewegung.

Bisher habe ich mir das so gedacht, was ich aber irgendwie nicht 
sonderlich elegant finde:

signed int xMovement; //16 Bit signed
unsigned char byte[3]; //8 Bit unsigned

xMovement = (byte[0] & 0b00010000); //Vorzeichenbit holen (Bit 4)
xMovement = (xMovement << 11); //an Bit 15 (11+4) schieben.
xMovement += byte[1]; //Dazu das Lowbyte addieren.

yMovement = (byte[0] & 0b00100000);//Vorzeichenbit holen (Bit 5)
yMovement = (yMovement << 10); //an Bit 15 (10+5) schieben.
yMovement += byte[2]; //Dazu das Lowbyte addieren.

Achja, die Variablen Typen sind vorgegeben und nicht verhandelbar...

Danke für Ideen!

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim T. wrote:
> xMovement = (byte[0] & 0b00010000); //Vorzeichenbit holen (Bit 4)
> xMovement = (xMovement << 11); //an Bit 15 (11+4) schieben.

Du überschreibst die vorrausgegangene Operation. Der Operator des 
zweiten Befehls sollte statt der Zuweisung ein "|=" sein. Ausserdem 
solltest du xMovement anfangs initialisieren.... am besten mit 0

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

Bewertung
0 lesenswert
nicht lesenswert
Das wird so nicht funktionieren.
Du kannst nicht einfach nur das Sign Bit an die höchstwertige
Stelle verschieben und hoffen, dass die entstehende Zahl dann
schon eine korrekte 2-er Komplementzahl ist.

  xMovement = byte[0];
  if( byte[0] & 0b00010000 )
    xMovement |= 0xFF00;

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Niels Hüsken wrote:
> Tim T. wrote:
>> xMovement = (byte[0] & 0b00010000); //Vorzeichenbit holen (Bit 4)
>> xMovement = (xMovement << 11); //an Bit 15 (11+4) schieben.
>
> Du überschreibst die vorrausgegangene Operation. Der Operator des
> zweiten Befehls sollte statt der Zuweisung ein "|=" sein. Ausserdem
> solltest du xMovement anfangs initialisieren.... am besten mit 0

Ja, die will ich ja überschreiben.
Nach der ersten Anweisung sieht xMovement (wenn die Maus in Negative 
x-Richtung bewegt wurde) so aus: 00000000 00010000.
Nach der 2. so: 10000000 0000000.
Ok, ich hätte auch schreiben können:
xMovement <<= 11;

xMovement initialisiere ich bei der Deklaration mit 0, hatte die 
Deklaration hier nur reingeschrieben um die Typen deutlich zu machen, 
allerdings das auch eher aus Gewohnheit. Spätestens beim Shiften wandert 
irgendwelcher Müll nach Links über die Klippe...

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Das wird so nicht funktionieren.
> Du kannst nicht einfach nur das Sign Bit an die höchstwertige
> Stelle verschieben und hoffen, dass die entstehende Zahl dann
> schon eine korrekte 2-er Komplementzahl ist.
>
>   xMovement = byte[0];
>   if( byte[0] & 0b00010000 )
>     xMovement |= 0xFF00;

Args, stimmt ich Depp. Verdammtes 2er Komplement, natürlich muss das 
Highbyte dann komplett hoch.

Demnach sollte es dann so gehen:
xMovement = byte[1];
if (byte[0] & 0b00010000) xMovement |= 0xFF00;

Eine Frage dann noch: Wird bei xMovement = byte[1]; das Highbyte von 
xMovement sicher genullt?

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

Bewertung
0 lesenswert
nicht lesenswert
Tim T. wrote:

> Eine Frage dann noch: Wird bei xMovement = byte[1]; das Highbyte von
> xMovement sicher genullt?

Ja. Weil byte ein unsigned Typ ist.

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Tim T. wrote:
>
>> Eine Frage dann noch: Wird bei xMovement = byte[1]; das Highbyte von
>> xMovement sicher genullt?
>
> Ja. Weil byte ein unsigned Typ ist.

Ok, das ist doch schonmal was. Ist das bei signed anders? Sorry, ich hab 
noch nicht mit gemischten Typen gearbeitet, jedenfalls nicht im signed 
Bereich. Wo findet man Infos über sowas?

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

Bewertung
0 lesenswert
nicht lesenswert
Tim T. wrote:
> Karl heinz Buchegger wrote:
>> Tim T. wrote:
>>
>>> Eine Frage dann noch: Wird bei xMovement = byte[1]; das Highbyte von
>>> xMovement sicher genullt?
>>
>> Ja. Weil byte ein unsigned Typ ist.
>
> Ok, das ist doch schonmal was. Ist das bei signed anders?

Logich.
Aus
  signed char -1
muss ja
  signed int -1
bei einer Zuweisung werden.

signed char i = -1;
signed int j;
  j = i;

> Sorry, ich hab noch nicht mit gemischten Typen gearbeitet,
> jedenfalls nicht im signed Bereich.

Die wichtigste Regel: Hast du 2 Datentypen, die sich nur durch
signed/unsigned unterscheiden (also signed/unsigned char, signed/
unsigned int), so wird immer der signed Typ auf unsigned umgecastet.

  signed char i = -1;
  unsigned char j = 24;


  if( i > j )    ist wahr, weil -1 in unsigned Schreibweise (*) 255 
ergibt.


> Wo findet man Infos über sowas?

In letzter Konsequenz in den ISO Dokumenten, die die Sprache 
beschreiben.
Die sind aber sehr unübersichtlich


(*) natürlich nur, wenn der Compiler auch 2-er Komplement benutzt.
Das muss er nicht tun, ich kenne aber keinen der es nicht tut.

Autor: Tim T. (tim_taylor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aha, sogesehen logisch, hatte nur nicht erwartet das der Compiler sich 
drum kümmert das z.B. die Werte von signed char und signed int 
übereinstimmen. Dachte er würde dabei nur das Lowbyte berücksichtigen:

Dachte der Macht aus
 -1 =          11111111 //8 Bit signed
255 = 00000000 11111111 //16 Bit signed

aber schön das er mitdenkt^^

richtig wäre demnach also: -1 = 11111111 1111111 und mir ist klar warum 
das Highbyte nicht genullt wird...

Besten Dank für Deine Infos, hab wieder was gelernt.

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.