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.
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 :-)
?
Ü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
??
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.
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.
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.
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.
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
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.