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?
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?!?
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
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
John schrieb:> Nicht mit <<. Das shiftet Bits. Zuweisung mit =.>> ADWEN = 1;
man kann einer konstanten nicht zuweisen.
zum Schluss steht da einfach nur
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.
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);
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...
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äää
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.
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.
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.
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....
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?
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.
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?!
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
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.
[*]
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?
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
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??!
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.
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.