Forum: Mikrocontroller und Digitale Elektronik Unterschied zw. ^ und ~


von Doran S. (utzer)


Lesenswert?

Hallo,

ich habe eine Variable
1
uint16_t Frequenz;
und am kompletten PortB des ATtiny2313 sind Taster angeschlossen.
Über diese Taster wird ein Wert (8 Bit, da 8 Taster) in den AVR eingeben 
(0 bis 255).
Dieser Wert soll zu 875 dazu gerechnet werden.
Soweit wäre das ja auch kein Problem, würde das einfach so machen:
1
Frequenz = 875 + PINB;
Da aber die Taster die Pins auf GND ziehen die internen Pullups 
aktiviert sind, muss ich die einzelnen Bits in 'PINB' zuvor invertieren.
Eigentlich wollte ich es so machen:
1
Frequenz = 875 + ~PINB
Aaber irgentwie hat das nicht so gut geklappt, da fehlt immer irgentwas.
Das hier...
1
Frequenz = 875 + (PINB ^ 0xFF);
...funktioniert perfekt.

Kann mir jemand auf die Sprünge helfen, was der Unterschied zwischen 
diesen beiden Varianten ist, und warum das eine funktioniert, aber das 
andere nicht?

Gruß
Doran

von blub (Gast)


Lesenswert?

Hm.... ~ sollte eigentlich funktionieren? Was sagt das lss-file?

von Klaus W. (mfgkw)


Lesenswert?

875 + ~PINB wird als int gerechnet, also in 2 Byte.
Außerdem wirfst du signed und unsigned durcheinander.

Vorschlag:
Frequenz = 875u + (uint8_t)(~PINB);

von Doran S. (utzer)


Lesenswert?

Hallo,

ok, dann werde ich es mal mit Frequenz = 875u + (uint8_t)(~PINB); 
versuchen.
Ist denn Frequenz = 875 + (PINB ^ 0xFF); auch ok, oder ist das andere 
aus irgendeinem Grund besser?

Doran

von Klaus W. (mfgkw)


Lesenswert?

PINB ^ 0xFF macht keinen Sinn, auch wenn das richtige Ergebnis 
rauskommt. Du willst negieren, also schreibt man das auch besser so hin 
(~PINB).
Es drückt dann die Absicht aus und verwirrt nicht.

Wenn du schreiben würdest, was nicht geht bzw. was falsch rauskommt, 
könnte man sinnvoller helfen.
Bis dahin gehe ich davon aus, daß nicht das Negieren Probleme macht, 
sondern die signed-Rechnung, wo du eigentlich unsigned haben willst (875 
ist erstmal int, also signed, und die Addition wird deshalb in signed 
durchgeführt, wofür dein Port-Wert entsprechend erweitert wird und bei 
gesetztem obersten Bit entsprechend falsch).

von Stefan E. (sternst)


Lesenswert?

Klaus Wachtler schrieb:
> Bis dahin gehe ich davon aus, daß nicht das Negieren Probleme macht,
> sondern die signed-Rechnung, wo du eigentlich unsigned haben willst (875
> ist erstmal int, also signed, und die Addition wird deshalb in signed
> durchgeführt, wofür dein Port-Wert entsprechend erweitert wird und bei
> gesetztem obersten Bit entsprechend falsch).

Nein, denn ein Port ist als uint8_t definiert, es findet also keine 
Vorzeichenerweiterung statt. Das Problem entsteht tatsächlich beim 
Invertieren, denn die Erweiterung auf int findet natürlich vorher statt.

von Doran S. (utzer)


Lesenswert?

Also Frequenz = 875u + (uint8_t)(~PINB); funktioniert!
Ohne das 'u' bei 875 oder ohne (uint8_t) funktioniert es nicht, und es 
stimmt ein/mehrere Bit(s) nicht. ()

Danke für die Tipps und Erklärungen,
Doran

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.