Hi, wenn ich bei einem ATMEGA162 PortE (Ausgang) beschreiben,in C, will geht es auf folgendes weise? PORTE=0b001 BSP: Für PE0 =1 und alles andere = 0? Oder muss ich schreiben 0b00000001 ? Hintergrund ist folgender, ich habe eine Schaltung bei der ich den Fehler nicht finde. Und nun suche ich gerade ohne Zugriff auf die Schaltung selbst den Fehler zu finden. Und bei dem Punkt im Programm war ich mir unsicher. Danke für eure Hilfe :-)
@Johannes (Gast) >PORTE=0b001 BSP: Für PE0 =1 und alles andere = 0? Ja. >Oder muss ich schreiben 0b00000001 ? Nein. Führende Nullen kann man weglassen. Besser ist es jedoch, sinnvolle Namen für die Bits zu nutzen, das macht die Sache deutlich besser lesbar, siehe Bitmanipulation.
Johannes schrieb: > Hi, > > wenn ich bei einem ATMEGA162 PortE (Ausgang) beschreiben,in C, will geht > es auf folgendes weise? > > PORTE=0b001 BSP: Für PE0 =1 und alles andere = 0? > > Oder muss ich schreiben 0b00000001 ? Auch zu beachten ist, dass nur der GCC diese Schreibweise versteht. Universeller ist es mit Hexnotation: PORTE = 0x01; Am besten macht man es aber wie in dem von Falk verlinkten Artikel, dann werden auch nur die Bits manipuliert, welche im Code stehen und nicht alle auf ein mal...
Ich schrieb: > Auch zu beachten ist, dass nur der GCC diese Schreibweise versteht. > Universeller ist es mit Hexnotation: PORTE = 0x01 Wahrscheinlicher ist es daß andere Compiler diese Notation irgendwann ebenfalls unterstützen werden als daß ein zukünftiger gcc das irgendwann aus heiterem Himmel plötzlich nicht mehr kann. Insofern also ist also das nun wirklich des OP's geringstes Problem. Gegen die binären Zahlenliterale 0b.... ist also überhaupt nichts einzuwenden, sie machen manches deutlicher, bzw tragen zur Selbstdokumentation des Codes bei, machen die Bedeutung oder das Zustandekommen, bzw den angedachten Verwendungszweck einer solchen Konstante deutlicher. Edit: Habe gerade gelesen daß die 0b Integer-Literale im nächsten offiziellen C++-Standard offiziell enthalten sein werden, also wird das wohl auch die C-Compiler-Hersteller und das C-Sprachkomitee stärker motivieren etwas praxisnäher zu denken.
:
Bearbeitet durch User
Hallo Johannes, Du weisst aber schon, dass vor der Bitausgabe der PortE bzw. die entsprechenden Bits des Ports erst über das DDRE auf Ausganggeschaltet werden müssen?! #define MEINTESTBIT_E0 0 DDRE |= (1<<MEINTESTBIT_E0); // PortPin als Ausgang PORTE |= (1<<MEINTESTBIT_E0); // Ausgang auf HIGH setzen : PORTE &= ~(1<<MEINTESTBIT_E0); // Ausgang auf LOW setzen
Hallo, danke schonmal für eure Hilfe :-) Ja die Ausgänge sind entsprechend gesetzt als Ausgang, habe allerdings dort DDRE=0xFF; geschrieben. Aber das sollte doch kein Problem sein oder? Problem bei meinem vorhaben ist, dass ich eine bereits vorhandene Schaltung ansteuere, von der ich nur durch durchpiepsen herausgefunden habe wie sie funktioniert (Keine uC vorhanden). Nun bin ich mir halt nicht sicher wo wirklich der Fehler liegt.
Noch eine Frage: Wenn ich mit "if(!(PINC & 0b10000000))" nach PINC7 abfrage, ist der Befehl so ok? Oder müssen dann alle anderen Eingänge zwingend=0 sein? Der Grund warum ich nicht if ( !(PINC & (1<<PINC7)) schreibe ist folgender, ich frage zuerst PINC ab und speicher es in eine uint_8t Array Variable. Der eigentliche Befehl sieht dann so aus: if(!(data[3] & 0b10000000))
Du solltest dir mal klar machen was das "&" bedeutet und was "PinC7". Damit verundest du das Byte vor dem "&" und danach. Ob du jetzt "& 0b10000000" oder "& (1<< PinC7)" schreibst ist egal, denn PinC7 ist nichts anderes "0b1000000" Steht so in den #defines
Ich habe kurz nocheinmal eine Frage: Wenn ich z.b. Schreibe: uint_8t data; data=PINC; und dann abfragen will ob Bit PC7 zum Zeitpunkt beim kopieren in dummy gesetzt war, geht das dann folgendermaßen? if(data & 0b10000000) Oder habe ich da irgendwo den Denkfehler? Ich vermute an der Stelle meinen Fehler, da ich so an die ersten vier Bits rankomme, aber nicht an PC4...7 Würde mich über eine Antwort sehr freuen :-)
Gerald M. schrieb: > denn PinC7 ist nichts anderes "0b1000000" Und (1 << PinC7) damit gleich
1 | 0b10000000000000000000000000000000000000000000000000000000000000000 |
? Überleg dir das noch mal... Johannes schrieb: > Ich habe kurz nocheinmal eine Frage: > Wenn ich z.b. Schreibe: > > uint_8t data; > data=PINC; > > und dann abfragen will ob Bit PC7 zum Zeitpunkt beim kopieren in dummy > gesetzt war, geht das dann folgendermaßen? > > if(data & 0b10000000) Ja, ich würde aber die (1 << PINC7) Notation verwenden, da man damit auf dem ersten Blick sihet um welches bit es geht und Fehler durch eine vergessene 0 vermeidet.
@Johannes (Gast) >und dann abfragen will ob Bit PC7 zum Zeitpunkt beim kopieren in dummy >gesetzt war, geht das dann folgendermaßen? >if(data & 0b10000000) Ja. >Oder habe ich da irgendwo den Denkfehler? Nein. >Ich vermute an der Stelle >meinen Fehler, da ich so an die ersten vier Bits rankomme, aber nicht an >PC4...7 ??
Ich habe folgenden ISR:
1 | ISR (TIMER0_COMP_vect){ |
2 | |
3 | |
4 | inv++; |
5 | |
6 | if (inv==0xFF){PORTB ^= (1<<PB4);} //LED Blinken lassen |
7 | |
8 | switch (adress) |
9 | {
|
10 | case 0: |
11 | data[3]=PINC; |
12 | PORTE=0x00; |
13 | |
14 | break; |
15 | |
16 | case 1: |
17 | data[0]=PINC; |
18 | PORTE=0b01; |
19 | |
20 | break; |
21 | |
22 | case 2: |
23 | data[1]=PINC; |
24 | PORTE=0b10; |
25 | |
26 | break; |
27 | |
28 | case 3: |
29 | data[2]=PINC; |
30 | PORTE=0b11; |
31 | break; |
32 | }
|
33 | |
34 | adress++; |
35 | if (adress==4){adress=0;} |
36 | |
37 | |
38 | }
|
Damit will ich in abhängigkeit von PORTE das was an PINC anliegt abspeichern. Später will ich dann auf das Array data darauf mit o.g. Befehl prüfen welche Bits gesetzt sind. Und das funktioniert nur für die Bits 0..3 für 4..7 geht es nicht? Die Lösung mit dem ISR habe ich gewählt, weil der Zustand von PORTE alle x ms geändert werden muss, sonst schaltet ein Watchdog die andere angeschlossene Schaltung ab. data ist global als volatile uint_8t definiert.
:
Bearbeitet durch User
Johannes schrieb: > Und das funktioniert nur für die Bits 0..3 für 4..7 geht es nicht? Und nochmal die Frage. Hast du das JTAG Interface per Fuse abgeschaltet? Per Default ist es nämlich eingeschaltet. Und es arbeitet auf den Pins .... tadaaaaa .... PC4 bis PC7. Was soviel bedeutet wie: du kannst dann die Pins nicht selbst benutzen.
:
Bearbeitet durch User
Bernd K. schrieb: > Edit: Habe gerade gelesen daß die 0b Integer-Literale im nächsten > offiziellen C++-Standard offiziell enthalten sein werden, also wird das > wohl auch die C-Compiler-Hersteller und das C-Sprachkomitee stärker > motivieren etwas praxisnäher zu denken. Ja, und in villeicht 200 Jahren oder so denken dann vielleicht sogar die C-Sprachgewaltigen darüber nach, ob es vielleicht sinnvoll wäre, diesen seit mindestens 30 Jahren schon vollkommen nutzlosen Oktalkram rückstandsfrei zu entsorgen. DAS würde nämlich die Kompatibilität zu praktisch ALLEN anderen heute relevanten Programmiersprachen massiv erhöhen. Und wer weiß, wie die Lage erst in 200 Jahren ist wäre...
Bernd K. schrieb: > Ich schrieb: >> Auch zu beachten ist, dass nur der GCC diese Schreibweise versteht. >> Universeller ist es mit Hexnotation: PORTE = 0x01 > > Wahrscheinlicher ist es daß andere Compiler diese Notation irgendwann > ebenfalls unterstützen werden als daß ein zukünftiger gcc das irgendwann > aus heiterem Himmel plötzlich nicht mehr kann. Insofern also ist also > das nun wirklich des OP's geringstes Problem. Es ist kein Problem solange der GCC benutzt wird (was spätestens wenn man sich mal mit ARM beschäftigt hat durchaus nicht immer der Fall sein muss), ist nur als Hinweis gedacht. > Gegen die binären Zahlenliterale 0b.... ist also überhaupt nichts > einzuwenden, sie machen manches deutlicher, bzw tragen zur > Selbstdokumentation des Codes bei, machen die Bedeutung oder das > Zustandekommen, bzw den angedachten Verwendungszweck einer solchen > Konstante deutlicher. Doch, Portierbarkeit. > Edit: Habe gerade gelesen daß die 0b Integer-Literale im nächsten > offiziellen C++-Standard offiziell enthalten sein werden, also wird das > wohl auch die C-Compiler-Hersteller und das C-Sprachkomitee stärker > motivieren etwas praxisnäher zu denken. Ja, aber das ist aktuell noch Zukunftsmusik.
Johannes scheint kein Profi zu sein und wer heute mit dem GCC bastelt, der braucht sich keine Sorgen zu machen morgen auf einen anderen inkompatiblen "Profi"-Compiler wechseln zu müssen. Und wer keine Binärzahlen versteht, der kommt natürlich auch nicht mit Oktalzahlen zurecht. Abschaffen muß man sie deshalb nicht, denn es gibt immer noch die Anderen ;-)
Bernd K. schrieb: > Edit: Habe gerade gelesen daß die 0b Integer-Literale im nächsten > offiziellen C++-Standard offiziell enthalten sein werden Curious: wo hast du das gelesen? Hintergrund: ich hatte die derzeitige GCC-Implementierung dafür damals auch und vor allem deshalb durch die Instanzen gedrückt, weil mich der lapidare Satz im C99-Rationale “A proposal to add binary constants was rejected due to lack of precedent and insufficient utility.” angepiept hat und ich wenigstens wollte, dass sie beim nächsten Mal nicht mehr einen “lack of precedent” konstatieren können … insofern ist es nett, wenn jetzt zumindest C++ das mal aufgegriffen haben sollte. Natürlich war GCC keineswegs der erste Compiler, der das konnte.
:
Bearbeitet durch Moderator
Bastler schrieb: > Und wer keine Binärzahlen versteht, der kommt natürlich auch nicht mit > Oktalzahlen zurecht. Abschaffen muß man sie deshalb nicht, denn es gibt > immer noch die Anderen ;-) Beitrag "Re: Witz der Woche"
Bastler schrieb: > wer heute mit dem GCC bastelt, > der braucht sich keine Sorgen zu machen morgen auf einen anderen > inkompatiblen "Profi"-Compiler wechseln zu müssen. Ich schätze mal wenn man alle Maschinenbefehle die in allen Prozessoren der ganzen Welt zusammengenommen heute morgen zwischen 00:00:00 und 00:00:01 UTC irgendwo auf der Welt ausgeführt wurden, wenn man von jedem einzelnen aufschreiben würde aus welchem Compiler er irgendwann mal rausgefallen ist dann würde man wahrscheinlich feststellen das der "Bastelcompiler" doch ganz schön beliebt zu sein scheint. Wer traut sich ne Schätzung zu?
Ok, ich geb's zu, die Ironie hab ich zu gut versteckt. Es war eigentlich die Antwort auf die Frage, ob man sich auf die GCC Erweiterung "Dualzahlkonstante" einlassen kann. Man kann, denn einem Hobbyist wird so schnell nichts besseres unterkommen. Nur Assemblerhelden sind (vermeintlich) besser. Ich hab vor 26 Jahren in einer 32-Bit DOS Umgebung zum ersten mal diesen Compiler benutzt, hab ihn nicht sofort geliebt, baue ihn aber inzwischen für den AVR selbst an und bin begeistert, was man für den Preis bekommt. Wir stehen also auf der selben Seite ;-)
Was ist eigentlich der Unterschied zwischen flag = (1<<BIT7); und flag = _BV(BIT7); bzw. was ist wann richtig eingesetzt? Weil, zum einen steht im Buch "Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie" geschrieben, das die GNU Makros BV, _BV veraltet seien, und man lieber die form (1<<XX) verwenden solle, zum anderen ein netter Hinweis, aus Kompatbilitätsgründen sollte ich lieber die BV Makros benutzen.
_BV(n) ist das Macro, das (1<<(n)) produziert, d.h. es ist das Gleiche.
BirgerT schrieb: > das die GNU Makros BV, _BV veraltet seien BV gab's wirklich mal, wurde aber vor mehr als 10 Jahren aus dem Verkehr gezogen, weil er doch recht intrusiv in den application namespace eingreift. Als Ersatz wurde dann _BV ins Leben gerufen, aber ich wüsste nicht, wer ihn warum als „veraltet“ deklariert hätte. ;-) Der einzige Grund für die Existenz dieses Makros ist, dass sich
1 | REGX = _BV(BITA) | _BV(BITB) | _BV(BITC); |
geringfügig besser liest als
1 | REGX = (1 << BITA) | (1 << BITB) | (1 << BITC); |
Ansonsten ist seine Verwendung Geschmackssache.
Ich schrieb: > Doch, Portierbarkeit. Die Bit-Konstanten hat man, wenn man irgendwann einen kommerziellen Proficompiler benutzen muss, in ein paar Minuten mit einer Scriptsprache der eigenen Wahl automatisch ersetzt. Und Code, in dem solches Bitgefrickel oberhalb der untersten HW-Abstraktionsschicht, die beim Portieren komplett ausgetauscht wird, betrieben wird, ist sowieso nicht ohne größeren Aufwand portierbar.
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.