hi, wenn ich z.B eine abfrage eines pins vornehmen möchte funktioniert das ja z.B über if (!(PINB&(1<<PB3))) soweit ich das verstanden hab ist das so: PINB= angenommener Zustand: 1111 1111 dies wird mit 0000 1000 mit einem UND verknüpft : wenn die beiden zusammen an der stelle (PB3) nicht wahr sind würde ja die if abfrage durchlaufen. warum wird bei dem satz (1<<PB3) anscheinend immer ein leere 8 bit kombination vorrausgesetzt (0000 0000) kann man dies beeinflussen? z.b 0000 0000 0000 0000? hoffentlich ist das einigermaßen verständlich^^
Beim Bitshift (1<<PB3) wird eine "1" um 3 Stellen nach links geshiftet. Die Definition in C ist , daß beim Shiften immer mit Nullen aufgefüllt wird. Wenn die Prozessorachitektur 8 bit ist, wird daraus 0000 1000. Bei 16 Bit wird daraus 0000 0000 0000 1000. Man kann dies auch z.B. durch sogenanntes casten erreichen, z.B. mit (uint16_t) (1<<PB3).
xMcx schrieb: > z.b 0000 0000 0000 0000? Wozu das denn? Dein PINB Register ist nur 8Bit lang, so macht es keinen Sinn diesen mit z.B. 0100 0000 0000 0000 zu vergleichen.
ja das schon aber warum weiß er, dass er dort ein ein 8 Bit Register verwendet? Wenn man also irgendwo z.B (1<<3) schreibt macht er daraus 0000 1000 ?
Mit 1<<3 sagst du ja das im 1. Byte eine 1 geshiftet wird und nicht darüber hinaus (1 Byte kleinster Datentyp). Würde jetzt mit 16Bit verglichen werden werden Reststellen mit 0 gefüllt!
sry, hab das oben von Lutz nicht gelesen. Danke, das ist die Antwort. Also ist das praktisch bei einer 8- Bit Architektur vorgegeben außer man schreibt es selber vor wie du geschrieben hast. Danke^^
Die Berechnungen werden als int durchgeführt. PINB wird zum int erweitert und das (1<<PB3) ist sowieso ein int. Sinnvoller wäre es daher die 1 zu casten. Die ist ein int. Wenn du ((long)1<<4) schreibst klappt das auch wenn sizeof(long) != sizeof(int) ist.
noch eine Frage Annahme: uint16_t i=0; i=(255<<8); i=|255; weiß grad nicht ob man die 255 so da rein schreiben kann aber mir geht es um das Verständnis. Passiert hier das: i= 0000 0000 0000 0000 i=(255<<8); i= 1111 1111 0000 0000 i=|255; i= 1111 1111 1111 1111 ?????
xMcx schrieb: > i=|255; Wenn du "i |= 255;" oder "i |= 0xFF;" schreibst, ist es tatsächlich so wie du sagst. mfg mf
Hi, xMcx schrieb: > hi, wenn ich z.B eine abfrage eines pins vornehmen möchte funktioniert > das ja z.B über > > if (!(PINB&(1<<PB3))) > > soweit ich das verstanden hab ist das so: > PINB= angenommener Zustand: 1111 1111 > dies wird mit 0000 1000 > mit einem UND verknüpft : if() wertet aus, ob das Ergebnis == 0 (0b00000000) ist, also False -- die if()-Bedingung ist dann nicht erfüllt. Wenn irgendein Bit im Ergebnis gesetzt ist, dann ist das Ergebnis != 0, also True: die if()-Bedingung ist erfüllt, und Dein Programm springt in den if()-Block. Anders gesagt: 0 ist äquivalent zu False, alles andere ist True -- das ist der ganze Trick.
1 | . 1111 1111 |
2 | & 0000 1000 |
3 | ------------ |
4 | = 0000 1000 == 8 == True |
5 | |
6 | . 1111 0111 |
7 | & 0000 1000 |
8 | ------------ |
9 | = 0000 0000 == 0 == False |
Das geht auch mit mehreren Bits -- sobald nur eines der gewünschten Bits gesetzt ist, wird der Ausdruck True:
1 | . 1111 1101 |
2 | & 0000 1010 |
3 | ------------ |
4 | = 0000 1000 == 8 == True |
5 | |
6 | . 1111 1111 |
7 | & 0000 1010 |
8 | ------------ |
9 | = 0000 1010 == 10 == True |
10 | |
11 | . 1111 0111 |
12 | & 0000 1010 |
13 | ------------ |
14 | = 0000 0010 == 2 == True |
15 | |
16 | . 1111 0101 |
17 | & 0000 1010 |
18 | ------------ |
19 | = 0000 0000 == 0 == False |
> warum wird bei dem satz (1<<PB3) anscheinend immer ein leere 8 bit > kombination vorrausgesetzt (0000 0000) Naja, ich versuch's mal so zu erklären: Du shiftest eine Eins in Nichts. Das Nichts ist per Definition 0. Oder 0b0000000 ... you get the idea. > kann man dies beeinflussen? Ja, indem Du eine Variable mit dem gewünschten Wert vorbelegst, und dann wendest Du Deine Bitoperation auf die Variable an.
1 | int asdf = 160; // --> 0b10100000 |
2 | asdf |= (1<<2); // drittes Bit von rechts setzen --> 0b10100100 |
3 | asdf &= ~(1<<2); // drittes Bit von rechts löschen --> 0b10100000 |
HTH, Klaus
Vielen Dank auch hierfür =). Mich plagt noch ein kleines Problem (hoffentlich das letzte) und zwar: Im Datenblatt des atmega 168 steht zum USART: 19.10.1 UDRn – USART I/O Data Register n, dieses besteht soweit ich sehe aus 2* 8 Bit-Register Wenn ich nun im Programm schreibe: UDR = x; Dann muss er ja x in das Write Register schreiben. Wäre diese Operation gleich wie das hier TXB = x; ? ersetzt der Compiler automatisch beim Schreibzugriff das UDR durch TXB und beim Lesezugriff durch RXB? oder was passiert da?
xMCx schrieb: > 19.10.1 UDRn – USART I/O Data Register n, > > dieses besteht soweit ich sehe aus 2* 8 Bit-Register Ja. Aber nur deshalb, weil dein Mega auch 2 unabhängige UART hat. das n in der Beschreibung ist so zu verstehen, dass es anzeigt, welche UART gemeint ist. UDR0 .... die UART, die Datenblatt überall als die UART 0 bezeichnet wird, und deren Pins laut ANschlussschema des Prozessors auch entsprechend zugeordnet sind. UDR1 .... die UART, die im Datenblatt überall als die UART 1 bezeichnet wird, und deren Pins laut ANschlussschema des Prozessors auch entsprechend zugeordnet sind. man hätte da auch eine "rote" und eine "gelbe", oder eine "runde" und eine "eckige" UART einfügen können. Aber einfach Durchnummerieren ist nun mal das einfachst und es gibt keine Misverständnisse. > Wäre diese Operation gleich wie das hier > > TXB = x; ? Es gibt kein Register namens TXB. Zumindest keines, das du ansprechen könntest. Beim Schreiben auf UDR landet das Byte im AUsgangsregister von der UART, beim Lesen von UDR kommt das Byte aus dem Eingangsregister der UART
Wenn ich z.B schreibe UDR=x; woher weiß der dann das er das untere Register nehmen muss und beim Lesen x=UDR; das obere Register? Weiß nicht wie ich das schreiben soll, zweifel grad selber ;)
xMCx schrieb: > Wenn ich z.B schreibe UDR=x; woher weiß der dann das er das untere > Register NOch mal. Es gibt kein 'unteres' UDR Register. Wenn du mit der UART0 arbeitest, dann gibt es ein UDR0 Register. Wenn du mit der UART1 arbeitest, dann gibt es ein UDR1 Register. (d.h. beide existieren natürlich dauernd. Aber für dich ist immer nur dasjenige interessant, dass zu der UART gehört, mit der du arbeitest)
ja das schon aber das ist ja 16 Bit groß z.B das UDR0. 8- Bit zum Lesen, 8- Bit zum Schreiben oder? ich dachte das es da irgendeine Operation gibt wie beim ADC Register. Dort kann man glaub auch das Register direkt ansprechen obwohl es aus 2* 8 Bit Register besteht. x=ADC; Dort muss doch der Compiler oder sonst was auch festlegen wie der Wert von dem ADC in x kommt. die 16 Bit werden ja nicht auf einmal geschickt.
xMCx schrieb: > ja das schon aber das ist ja 16 Bit groß z.B das UDR0. NEIN > 8- Bit zum Lesen, 8- Bit zum Schreiben oder? NEIN UDR ist 8 Bit groß. Wie Atmel das intern macht, dass beim Schreiben das µC intern in einem anderen Siliziumareal landet als das von dem du die Daten bekommst, wenn du auf UDR lesend zugreifst .... das ist etwas, was dich nicht zu interessieren braucht. Du beschreibst UDR und schickst damit 8 Bit auf die Reise. 8-Bit Daten kommen rein, und du kriegst sie, indem du auf UDR lesend zugreifst. Atmel hat das im Datenblatt möglicherweise etwas verwirrend dargestellt. VOn den im Datenblatt zusammengefassten Prozessoren, Mega48, Mega88 und Mega168 verfügt keiner über 2 UARTS. n ist bei dir immer 0
Karl Heinz Buchegger schrieb: > Es gibt kein 'unteres' UDR Register. Er meint wohl was Anderes. UDRx ist ein gemeinsamer Name für 2 physikalisch getrennte Register. Beim Schreiben wird automatisch immer das Senderegister gewählt, beim Lesen wird automatisch immer das Empfangsregister gewählt. Es ist so wie mit dem "Briefkasten". Will man etwas versenden, so meint man die gelbe Kiste bei der Post, will man etwas bekommen, meint man den eigenen Briefkasten am Haus. Beides nennt man aber "Briefkasten", weil die Unterscheidung automatisch aus dem Kontext erfolgt. ...
xMCx schrieb: > ich dachte das es da irgendeine Operation gibt wie beim ADC Register. > Dort kann man glaub auch das Register direkt ansprechen obwohl es aus 2* > 8 Bit Register besteht. Das ist was völlig Anderes. ADC und 16-Bit-Timer haben 16-Bit-Register. Um auf diese atomar zugreifen zu können, wird ein Hilfsregister als Zwischenspeicher verwendet. Deshalb muss beim Lesen und Schreiben die richtige Reihenfolge von H-Byte und L-Byte eingehalten werden. ...
Hannes Lux schrieb: > Es ist so wie mit dem "Briefkasten". Will man etwas versenden, so meint > man die gelbe Kiste bei der Post, will man etwas bekommen, meint man den > eigenen Briefkasten am Haus. Beides nennt man aber "Briefkasten", weil > die Unterscheidung automatisch aus dem Kontext erfolgt. Gutes Beispiel. Muss ich mir merken. Wenn im Programm steht: "Schmeiss den Brief in den Briefkasten" dann ist der bei der Post gemeint. Steht im Programm "Hol den Brief aus dem Briefkasten" dann ist der im Flur gemeint, in den der Briefträger die Post reinlegt. im ersten Fall wäre das dann UDR = 'x'; // Das Bitmuster für x wird versandt der zweite Fall ist uint8_t i; i = UDR; // Da empfangene Bitmuster wird geholt rein nur durch die Verwendung bestimmst du, welches der beiden im Datenblatt im Kapitel UDR angegebene 'Register' TXB oder RXB benutzt wird.
Karl Heinz Buchegger schrieb: > Atmel hat das im Datenblatt möglicherweise etwas verwirrend dargestellt. > VOn den im Datenblatt zusammengefassten Prozessoren, Mega48, Mega88 und > Mega168 verfügt keiner über 2 UARTS. n ist bei dir immer 0 Die Autoren von Atmel stellen auf Textbausteine (wiederverwertbaren Text, so wie C-Programmierer wiederverwertbaren Code bevorzugen) um. Somit gilt ein UART-Kapitel (oder Timer, oder...) für alle künftigen AVRs, egal wie viele UARTs (oder andere Peri-Einheiten) dort implementiert sind. ...
hab ich das nun falsch formuliert? Tut mir echt leid, dass deine Nerven so belastet werden
>>UDRx ist ein gemeinsamer Name für 2 physikalisch getrennte Register. >>Beim Schreiben wird automatisch immer das Senderegister gewählt, >>beim Lesen wird automatisch immer das Empfangsregister gewählt. Das hat mir gefehlt. Ich hab mich gefragt wie er das Senderegister anwählt. Wo ist das definiert, dass er beim Senden UDR0=x; das Richtige Register nimmt, glaub das TXB wars. Das läuft aber dann intern ab? Vielen vielen Dank an alle
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.