Forum: Mikrocontroller und Digitale Elektronik 16 bit Variable in 8 bit und 2 bit aufteilen


von D a v i d K. (oekel) Benutzerseite


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

von Klaus (Gast)


Lesenswert?

Welcher PIC, da gibts durchaus Unterschiede

MfG Klaus

von THaala (Gast)


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.

von THaala (Gast)


Lesenswert?

Ah sorry -

mir ging das Wörtchen "PIC" durch. Daher nemhe ich alles zurück, da ich 
mich da nicht auskenne.

Gruß T

von D a v i d K. (oekel) Benutzerseite


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

von Klaus (Gast)


Lesenswert?

CCPR1L = pwm >> 2;
CCP1CONbits.DC1B = pwm & 0x3;

So sollte es gehen.

MfG Klaus

von D a v i d K. (oekel) Benutzerseite


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

von Karl H. (kbuchegg)


Lesenswert?

D a v i d K. schrieb:

> 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?

Ja
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.

von D a v i d K. (oekel) Benutzerseite


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

von Sven B. (scummos)


Lesenswert?

~ und ! ist nicht dasselbe. ! invertiert einen Wahrheitswert, ~ 
invertiert bitweise. ~0101 und 0101 sind zum Beispiel beide true, aber 
0101 ist true und !0101 ist false.

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.