16 bit Variable in 8 bit und 2 bit aufteilen

OP Persönliche Seite #3084670
Lesenswert?

Hi,

um Grunde geht es um das Register CCPR1L und CCPR1H.
CCPR1L beinhaltet die 8 MSB und CCPR1H die beiden LSB eines 10Bit Wertes 
(häufig PWM bei PIC)

Da ich in meinem Programmcode ja keine "uint10_t" haben und es diese 
wohl auch nicht gibt, muss ich die Variable als uint16_t anlegen.

Nun wird irgendwann diese in CCPR1L und CCPR1H geschoben.
Nun möchte ich eigentlich nur von euch wissen, ob folgender Code richtig 
ist und/oder optimiert werden kann:
1
uint16_t pwm = 0b0000001111111111;
2
CCPR1H = pwm; // ich erwarte, dass von 0b00000011111111xx nur 0bxx bleibt
3
CCPR1L = pwm >> 2;//...0b000000xxxxxxxx11 nur 0bxxxxxxxx bleibt

Dabei setze ich mir die 0bxxxxxxxx + 0bxx zu 0bxxxxxxxxxx im Geiste 
zusammen.

Richtig? (Gibt es vielleicht eine Möglichkeit dieses im Programmcode 
einfacher zu schreiben) -->Der Compiler/Debugger spielt mir irgendwie 
übel zu und behauptet die beiden Variablen hätten nach der Zuordnung aus
pwm = 00000011 10101011
CCPR1H = 11101010
CCPR1L = 11101010
Kann ich mir nicht wirklich erklären, denn die Linke Seite einer 
Zuweisung dürfe die Variable pwm doch nicht verändern. (?)

Grüße Oekel
Gast #3084714
Lesenswert?

D a v i d K. schrieb:
> uint16_t pwm = 0b0000001111111111;
> CCPR1H = pwm; // ich erwarte, dass von 0b00000011111111xx nur 0bxx bleibt
> CCPR1L = pwm >> 2;//...0b000000xxxxxxxx11 nur 0bxxxxxxxx bleibt

Nö - nicht richtig.
Die Annahme der Bitreihenfolge ist verkehrt:
in H gehört das 0b00000011
in L gehören die rechten 8 Bits.....

evtl. so:
uint16_t pwm = 0b0000001111111111;
CCPR1H = pwm<<8;
CCPR1L = pwm;

Sind da in CCPR1H evtl noch andere Bits drin deren Wert nicht verändert 
werden darf ?

Gruß T.
OP Persönliche Seite #3084728
Lesenswert?

THaala schrieb:

> evtl. so:
> uint16_t pwm = 0b0000001111111111;
> CCPR1H = pwm<<8;

Das kann ich mir nicht vorstellen. sagen wir Mal uint16_t foo = 3.
Nach meinem Wissen ist dann uint8_t baa = foo;
foo immer noch 3.

Binär betrachtet wäre das 0b00000000 00000011 und 0b00000011;
Nehme ich jetzt dein pwm = 0b0000001111111111 << 8;
erhalte ich 0b11111111 11000000; und dann gecastet 0b110000 bzw. 0b00.

Es handelt sich um den PIC16F1936 und ich glaube ich sollte lieber das 
HI-TECH C struct CCP1CONbits.DC1B verwenden, welches 2bit verwaltet.
Ehrlich gesagt bin ich mir bei dem CCPR1H nämlich überhaupt nicht 
sicher.
CCPR1L verwaltet definitiv 8bit.

Zitat 19.5.2: "The CCPRxL contains the eight MSbs and the DCxB<1:0>
bits of the CCPxCON register contain the two LSbs".
bit 5-4 vom CCPX CONTROL REGISTER. Dementsprechend dürfen die anderen 
nicht verändert werden. (Doch das wäre der nächste Schritt gewesen)

Grüße Oekel
OP Persönliche Seite #3084873
Lesenswert?

Danke!

Nur noch eine Kleinigkeit bezüglich des Bitweisen UND und dem normalen 
UND.
Angenommen ich misbrauche ein ganze uint8_t als "bool", sprich ich 
belege
uint8_t b_blub = 1;
uint8_t b_blub2 = 1;

Dann ist es doch in einer Abfrage völlig gleich, ob ich
if(b_blub & b_blub2)
oder
if(b_blub && b_blub2)
schreibe, oder?

Denn ich sehe effektiv keinen Unterschied zwischen
0<(0b00000001 & 0b00000001)
und
(0<0b00000001) & (0<0b00000001)

darauf läuft es doch hinaus oder?
(Sorry, bin etwas eingerostet, da ich mit Java, C++ und C# Jahrelang 
nicht über so etwas nachdenken musste)

Grüße Oekel
OP Persönliche Seite #3084936
Lesenswert?

Karl Heinz Buchegger schrieb:

> Aber nur unter deinen Voraussetzungen, dass die Variablen nur 0 oder 1
> enthalten.
> Sobald da andere Werte ins Spiel kommen, sieht die Sache anders aus.

Auch bei der Negation? Oder macht ein !b_blub aus 0b00000001 --> 
0b11111110
Dann könnte nämlich so etwas wie 0b00000001 & 0b11111110 = 0b11111111 
ergeben.
Erwartet wurde: TRUE (0b00000001) && !TRUE(0b111111110) = 
FALSE(0b00000000)
gerechnet wurde aber:
TRUE (0b00000001) & !TRUE(0b111111110) = TRUE(0b11111111)

Sprich: ist ! und ~dasselbe in ANSI C?
Ich weiß dass ~0b00000000 = 0b11111111 ist
und was ist !0b00000001 (siehe oben)

Grüße Oekel

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren