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


von Tim T. (tim_taylor) Benutzerseite


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:

1
signed int xMovement; //16 Bit signed
2
unsigned char byte[3]; //8 Bit unsigned
3
4
xMovement = (byte[0] & 0b00010000); //Vorzeichenbit holen (Bit 4)
5
xMovement = (xMovement << 11); //an Bit 15 (11+4) schieben.
6
xMovement += byte[1]; //Dazu das Lowbyte addieren.
7
8
yMovement = (byte[0] & 0b00100000);//Vorzeichenbit holen (Bit 5)
9
yMovement = (yMovement << 10); //an Bit 15 (10+5) schieben.
10
yMovement += byte[2]; //Dazu das Lowbyte addieren.

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

Danke für Ideen!

von Niels H. (monarch35)


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

von Karl H. (kbuchegg)


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;

von Tim T. (tim_taylor) Benutzerseite


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

von Tim T. (tim_taylor) Benutzerseite


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:
1
xMovement = byte[1];
2
if (byte[0] & 0b00010000) xMovement |= 0xFF00;

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

von Karl H. (kbuchegg)


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.

von Tim T. (tim_taylor) Benutzerseite


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?

von Karl H. (kbuchegg)


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.

von Tim T. (tim_taylor) Benutzerseite


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.

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.