Forum: Mikrocontroller und Digitale Elektronik Register in C setzen


von Tombo (Gast)


Lesenswert?

Hallo,
gefunden habe ich sowas als Beispiel

ADC1_CR1 = (AWDEN<<1) | (DUALMOD0<<1);
aber genauso gut kann ich doch auch nur
AWDEN<<1;
DUALMOD0<<1;

oder vielleicht sogar
(DUALMOD0<<1) | (AWDEN<<1);

schreiben?
klar, das erste ist natürlich erheblich übersichtlicher und klarer..aber 
wird das
ADC1_CR1 =
davor wirklich benötigt?

von Walter S. (avatar)


Lesenswert?

ja

von Peter II (Gast)


Lesenswert?

Tombo schrieb:
> aber genauso gut kann ich doch auch nur
> AWDEN<<1;
> DUALMOD0<<1;

und was soll das bringen?

Du kannst in C auch einfach
1
42;

schreiben, bringt den gleichen nutzen.

von Tombo (Gast)


Lesenswert?

das ich ds register damit setzte sol es bringen?!
in Pascal ginge es schlieslich so!
AWDEN:=1;
bzw
AWDEN_bit:=1;

und ich hätte damit das bit vom ADC gesetzet..tut es das nun in c auch 
oder nicht?!?

von Tombo (Gast)


Lesenswert?

die Frage ist doch klar gestellt!?!
Kann ich es auch so schreiben oder ist dann die Funktion nicht mehr 
gegeben?!

von Peter II (Gast)


Lesenswert?

Tombo schrieb:
> und ich hätte damit das bit vom ADC gesetzet..tut es das nun in c auch
> oder nicht?!?

nein, weil AWDEN ist kein Register sondern einfach eine Konstante.

Das Register ist: ADC1_CR1

von Christian (Gast)


Lesenswert?

Nein

AWDEN ist nichts anderes als ein beliebiges Wort das z.B. für die Zahl 4 
steht.

Der Ausdruck AWDEN<<1 heisst dann nichts weiter, als dass die 1 um 4 
bits nach links geshiftet wird.

aus

0000

wird dann

1000

nun muss der compiler aber noch wissen in welches Register er diesen 
Wert schreiben muss.

Daher

ADC1_CR1 = (AWDEN<<1)

Gruß
Christian

von Peter (Gast)


Lesenswert?

Tombo schrieb:
> die Frage ist doch klar gestellt!?!

Ja.

> Kann ich es auch so schreiben

Ja.

>oder ist dann die Funktion nicht mehr gegeben?!

Ja.

von John (Gast)


Lesenswert?

Nicht mit <<. Das shiftet Bits. Zuweisung mit =.

ADWEN = 1;

von Peter II (Gast)


Lesenswert?

John schrieb:
> Nicht mit <<. Das shiftet Bits. Zuweisung mit =.
>
> ADWEN = 1;

man kann einer konstanten nicht zuweisen.

zum Schluss steht da einfach nur
1
2 = 1;

und das bringt und außer einem Fehler.

von Walter S. (avatar)


Lesenswert?

Tombo schrieb:
> die Frage ist doch klar gestellt!?!

was ist an meiner Antwort unklar?!&§!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Tombo schrieb:
> Kann ich es auch so schreiben oder ist dann die Funktion nicht mehr
> gegeben?!

Nein, ja.

> ADC1_CR1 = (AWDEN<<1) | (DUALMOD0<<1);

Das ist eine Zuweisung. ADC1_CR1 ist das Register, dem ein Wert 
zugewiesen wird.

Dieser Wert berechnet sich aus den Konstanten AWDEN und DUALMOD0, 
die die Nummer eines Bits im Register definieren und deswegen 
entsprechend geschoben werden müssen.

Wenn Du einfach nur
(AWDEN<<1) | (DUALMOD0<<1);

schreibst, schreibst Du nur diesen Wert hin, d.h. der Wert landet 
nicht im zugehörigen Register.

Nochmal:

AWDEN und DUALMOD0 sind Konstanten, die die Nummern der Bits im 
Register wiedergeben. Sieh Dir die Definitionen in der zugehörigen 
Headerdatei an.

von John (Gast)


Lesenswert?

Ja stimmt schon. Aber es gibt ja auch bitadressierbare Register wo das 
dann so klappt. Generell würd ichs auch so machen wie oben von dir 
beschrieben. Nur andersrum ?
Also adc_cr1 = (1 << adwen);

von Tombo (Gast)


Lesenswert?

und warum shiftet man die dann?!
<<1 heißt doch um 1 nach links schieben..aber mögliche Werte sind doch 
nur 0 oder 1 um es zu aktivieren oder nicht zu aktivieren oder 
nicht?*kopfkratz*

Und warum geht es dann in Pascal?

hierauf greift es ja zu
1
sfr unsigned long   volatile ADC1_CR1             absolute 0x40012404;
2
    const register unsigned short int AWDEN = 23;
3
    sbit  AWDEN_bit at ADC1_CR1.B23;
4
    const register unsigned short int JAWDEN = 22;
5
    sbit  JAWDEN_bit at ADC1_CR1.B22;
6
    const register unsigned short int DUALMOD0 = 16;
7
    sbit  DUALMOD0_bit at ADC1_CR1.B16;

dort kann ich wie gesagt die Register mit
AWDEN_bit:=1;
ansteuern?!
Warum geht es dann in C nicht mit AWDEN_bit = 1;
Ok, vermutlich würde das auch funtkionieren, aber das mit dem shiften 
raffe ich nicht...

von Tombo (Gast)


Lesenswert?

nochmal wie ich ds vertseh was falsch ist..schon karl
adc_cr1 = (1 << adwen);

setze den wert von adwen auf 1 und weise dann adwen adc_crl zu..
ist natürlich quatsch weil adwen eine constante ist?!? und<< nicht 
zuweist sondenr verschiebt?!? häää

von Thomas E. (thomase)


Lesenswert?

Christian schrieb:
> ADC1_CR1 = (AWDEN<<1)

Rufus Τ. Firefly schrieb:
> ADC1_CR1 = (AWDEN<<1) | (DUALMOD0<<1);

Also wirklich.

John schrieb:
> Also adc_cr1 = (1 << adwen);

mfg.

von Tombo (Gast)


Lesenswert?

und was macht der | ?? ist der nur für die schöne optik? :-)

von Max H. (hartl192)


Lesenswert?

Tombo schrieb:
> und warum shiftet man die dann?!
Bitmanipulation

> Warum geht es dann in C nicht mit AWDEN_bit = 1;
Weil niemand AWDEN_bit entsprechend definiert hat. Machbar wäre es auf 
jedem Fall so ähnlich wie hier: 
Beitrag "AVR-Register als Bitfields"

von Thomas E. (thomase)


Lesenswert?

Tombo schrieb:
> setze den wert von adwen auf 1 und weise dann adwen adc_crl zu..
> ist natürlich quatsch weil adwen eine constante ist?!? und<< nicht
> zuweist sondenr verschiebt?!? häää

Kauf dir ein C-Buch.

mfg.

von LiPoFeFaFu (Gast)


Lesenswert?

Mit meinen sehr frischen Kenntnissen erklärt :

ADC1_CR1 ist das Register:

00000000

Du willst an Stelle AWDEN,nehmen wir 4, eine 1 haben, also (AWDEN<<1)

ergibt meiner Meinung nach

00001000

aber das muss ja noch ins Register !

also

ADC1_CR1 =  (AWDEN<<1)

Oder ?


//Pascal kann ich nicht.

von Peter II (Gast)


Lesenswert?

Tombo schrieb:
> nochmal wie ich ds vertseh was falsch ist..schon karl
> adc_cr1 = (1 << adwen);
>
> setze den wert von adwen auf 1 und weise dann adwen adc_crl zu..
> ist natürlich quatsch weil adwen eine constante ist?!? und<< nicht
> zuweist sondenr verschiebt?!? häää

adwen ist eine Kontante z.b. 4;
1
adc_cr1 = (1 << adwen);

also steht dort:
1
adc_cr1 = (1 << 4);

und was ist 1<<4 ?
1
adc_cr1 = 16

und genau das wird gemacht. Es wird eine 16 in das Register adc_cr1 
geschrieben.

von Thomas E. (thomase)


Lesenswert?

LiPoFeFaFu schrieb:
> //Pascal kann ich nicht.

Und C kannst du auch nicht.

mfg.

von LiPoFeFaFu (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> LiPoFeFaFu schrieb:
>> //Pascal kann ich nicht.
>
> Und C kannst du auch nicht.
>
> mfg.

Wenn man das jetzt umdreht (AWDEN<<1) -> (1<<AWDEN) und die 1 noch eins 
weiter schiebt 00010000 wirds richtiger....

von John (Gast)


Lesenswert?

10000b ist 16. War schon richtig.

von Tombo (Gast)


Lesenswert?

hmm.ok tatsächlich hilft mir das Peter II jetzt am ehesten..
Laut meiner mikroe source ist
1
sfr unsigned long   volatile ADC1_CR1             absolute 0x40012404;
2
    const register unsigned short int AWDEN = 23;
3
    sbit  AWDEN_bit at ADC1_CR1.B23;
4
    const register unsigned short int JAWDEN = 22;
5
    sbit  JAWDEN_bit at ADC1_CR1.B22;
6
    const register unsigned short int DUALMOD0 = 16;
7
    sbit  DUALMOD0_bit at ADC1_CR1.B16;


AWDEN=23

nur dann raffe ich es schon weider  icht..
dann würde doch
adc_cr1 = (1 <<23); da stehen..was bedeuten würde

er würde die 1 23 felder nach links schieben?!ß Aber es ist...ah 
ok..doch kalr ich ja jetzt eine 32bit CPU :-)
richtig?
Das ist nämlich vom ARM
Dann wären das
4194304 die er nach adc_crl schieben würde..wenn ich jetz noch
(1<<JAWDEN) shifte also die 1 um 22 nach links schiebe steht im register 
dann
6291456  und damit wären dann alle werte 000etc bist auf bit 22 und 23? 
richtig?

von Thomas E. (thomase)


Lesenswert?

LiPoFeFaFu schrieb:
> Wenn man das jetzt umdreht (AWDEN<<1) -> (1<<AWDEN) und die 1 noch eins
> weiter schiebt 00010000 wirds richtiger....

Also kannst du das ja doch.

mfg.

von Tombo (Gast)


Lesenswert?

warum wird im verlinkten Beispiel aber wiedeer
PORTB |= (1<<PORTB3);

geschrieben, ich hätte jetzt gedcht, das löscht das bit..aber weiter 
geht es dann mit
"könnte man dann einfacher schreiben mit:

  BF_PORTB.portb3 = 1;

bzw. noch kürzer:

  BFM_PORTB3 = 1;"

also doch kein löschen?!

von Max H. (hartl192)


Lesenswert?

Tombo schrieb:
> warum wird im verlinkten Beispiel aber wiedeer
> PORTB |= (1<<PORTB3);
>
> geschrieben, ich hätte jetzt gedcht, das löscht das bit
Da hast du falsch gedacht, das bit wird mit
1
PORTB &= ~(1<<PORTB3);
gelöscht.

> also doch kein löschen?!
Ja, zum Beispiel mit
1
BFM_PORTB3 = 0;

von Tombo (Gast)


Lesenswert?

warum dann das|= anstelle des = zum setzen des Bits?

von Max H. (hartl192)


Lesenswert?

Tombo schrieb:
> warum dann das|= anstelle des = zum setzen des Bits?
Mit dem = schreibst du im Beispiel von PORTB3 0b0000'1000 in den Port 
und setzt damit alle bit bis auf das dritte auf null.
Mit dem |= machst du das inklusive Oder* mit 0b0000'1000, lässt also 
alle bits bis auf das dritte, das gesetzt wird, unverändert.

Das bit PORTB3 wird mit beiden Methoden gesetzt, das zweite hat aber 
keine Auswirkung auf die restlichen bits des PORTs.

Genauer wird das im Artikel Bitmanipulation behandelt.

[*]
1
A   B   A oder B
2
0   0      0
3
0   1      1
4
1   0      1
5
1   1      1

: Bearbeitet durch User
von Tombo (Gast)


Lesenswert?

ahh ok, das war jetz hilfreich :-)
wenn ich nun aber schreiben würde..
5<<23

dann würde er das bitmuster von 5 um 23 stellen nach links verschieben 
oder funktioniert << nur mit 1?

von Tombo (Gast)


Lesenswert?

we..kein kritik an meinem Beispiel mit 1<<23?!?
Offensichtlich wäre das sehr wohl falsch .-(
"Integer Promotion"
reg_32 |= (1 << MEINBIT15);              /* FEHLER: Setzt die Bits 31 - 
15, da ((int)1 << 15) == 0xFFFF8000 */

reg_32 |= ((uint32_t)1 << MEINBIT15);    /* Hier wird nur Bit 15 
gesetzt. */
reg_32 |= (1U << MEINBIT15);             /* */
etc pp

von Tombo (Gast)


Lesenswert?

ist hier ein Fehler in dem Artikel?!?
http://www.mikrocontroller.net/articles/Bitmanipulation

DORT STEHT
Ist PORTB vorher z. B. 0b01111111, dann ist der Inhalt nach der 
Operation 0b011111111 and 0b11111010 = 0b01111010, die gewünschten Bits 
0 und 2 sind somit gelöscht.

ist bei 0b011111111  nicht die 0 hinter dem b falsch bzw henerell eine 
Stelle zu viel??!

von Max H. (hartl192)


Lesenswert?

Tombo schrieb:
> ist hier ein Fehler in dem Artikel?!?
> http://www.mikrocontroller.net/articles/Bitmanipulation
>
> DORT STEHT
> Ist PORTB vorher z. B. 0b01111111, dann ist der Inhalt nach der
> Operation 0b011111111 and 0b11111010 = 0b01111010, die gewünschten Bits
> 0 und 2 sind somit gelöscht.
Nein, kein fehler, dass passt schon so. Wieso sollte es einer sein?

> ist bei 0b011111111  nicht die 0 hinter dem b falsch bzw henerell eine
> Stelle zu viel??!
Ok, es sind 9 bit, das ändert aber nichts am Beispiel.

von Frank (Gast)


Lesenswert?

Tombo schrieb:
> Operation 0b011111111

9Bit?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Tombo schrieb:
> ist bei 0b011111111  nicht die 0 hinter dem b falsch bzw henerell eine
> Stelle zu viel??!

Da war eine '1' zu viel. Hab's gerade korrigiert.

von Tombo (Gast)


Lesenswert?

stimmt , jetzt stimmt :-) Jetzt macht es auch Sinn :-)

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.