Bit setzen/löschen in C?
Wie kann ich schreiben auf ein einzelnes bit? Ich habe eine variable, die entweder 1 oder 0 und I schreiben wollen, seinen Wert um ein einzelnes bit in einem 8-bit - reg
variable.
Ich weiß, das wird ein bit:
reg |= mask; //mask is (1 << pin)
- Und dies wird klar, ein bisschen:
reg &= ~mask; //mask is (1 << pin)
Gibt es eine Möglichkeit für mich, dies zu tun in einer Zeile code, ohne zu bestimmen, ob der Wert hoch oder niedrig ist, da der Eingang?
register
ist ein Schlüsselwort in C. Sie müssen nicht es verwenden, wie ein name.Ich machte eine änderung in der Frage:
register
zu reg
. Es braucht peer-Zulassung.Nicht sehen können, die Sie auf Warteschlange Bearbeiten, verändert es direkt.
InformationsquelleAutor tylerjw | 2013-09-01
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vorausgesetzt
value
ist0
oder1
:Benutze ich
REG
stattregister
denn als @KerrekSB wies darauf hin, in OP-Kommentare,register
ist ein C-Schlüsselwort.Die Idee hier ist, berechnen wir den Wert
REG
mit der angegebenen bit gelöscht, und dann je nachvalue
setzen wir das bit.GCC -O2
Für die Einschränkung den Wert auf {0,1} ich würde vorschlagen, zu verwenden... | ((!!value) << pin)
für den Allgemeinen Fall, ich denke, das ist sehr compiler-abhängig. Auf einigen Compilern würde ich Angst vor der Benutzung von logischen Operatoren wäre eigentlich hinzufügen einige branch-code.
IMHO müsste es Schleifen auf Architekturen, die nicht bitshift-Anweisungen in hardware (DEC alpha didnot haben, IIRC), aber die
reg = a | b;
selbst bedeutet nicht, dass eine Filiale, natürlich.oder MSP-430, die können bitweise Verschiebung nur ein wenig in einer Zeit.
IIRC die ersten 8088 konnte nicht verschoben werden, indem das CX-register noch nicht. (oder war es nur die 6502?)
InformationsquelleAutor ouah
Weil Sie getaggt dies mit embedded ich denke, die beste Antwort ist:
(die Sie können, wickeln Sie Sie in ein makro oder inline-Funktion). Der Grund dafür ist, dass embedded-Architekturen wie AVR haben, bit-set und bit-klare Anweisungen und die Kosten der Verzweigung ist nicht hoch im Vergleich zu anderen Anleitungen (wie auf eine moderne CPU mit spekulativer Ausführung). GCC identifizieren können, die Idiome in diesem
if
- Anweisung und erzeugt die richtigen Anweisungen. Eine komplexere version (auch wenn es astfreie, wenn geprüft auf modernen x86) möglicherweise nicht versammeln, um die besten Anweisungen, die auf einem eingebetteten system.Der beste Weg, um sicher wissen, ist, zerlegen Sie die Ergebnisse. Sie müssen nicht ein Experte zu sein (vor allem in embedded-Umgebungen), um die Ergebnisse auszuwerten.
if ( set) reg_set = mask; else reg_clr = mask;
. Register wird definiert alsvolatile
Objekte, die der compiler nicht haben das Recht zur Durchführung dieser Optimierung (=ersetzenreg
mitreg_set / reg_clr
) selbst.Ouah gibt gut beraten; Sie können nicht wirklich sagen, ob reg |= mask Ergebnisse in ein bit gesetzt ist oder eine lese-mofify-schreiben, das ist CPU und compiler-abhängige (ich würde sagen, es ist wahrscheinlicher, Ergebnisse, die in den späteren). In Fällen wie diesem, immer demontieren Sie den code, um zu sehen, was tatsächlich passiert.
InformationsquelleAutor Ben Jackson
Eines übersehen-Funktion von C ist, wenig Verpackung, welche ideal für eingebettete Arbeit. Sie definieren eine
struct
Zugriff auf jedes bit einzeln.Den
: 1
sagt dem compiler, dass Sie nur wollen, dass jeder variable 1 bit lang. Und dann nur noch Zugriff auf die Adresse der variablereg
sitzt auf, warf es auf Ihre bit-array und dann Zugriff auf die bits einzeln.®
ist die Adresse der variable.((T_BitArray *)®)
ist die gleiche Adresse, aber jetzt sind die complier denkt, dass es als einT_BitArray
- Adresse und die((T_BitArray *)®)->bit1
bietet Zugriff auf das zweite bit. Natürlich, es ist am besten, um aussagekräftigere Namen alsbit1
Das ist 100% nicht tragbar und unsicher. Unter Verwendung von bit-Feldern ist immer eine schlechte Idee, vor allem in embedded-Systemen. Nennen Sie das bit 7 in der oben nicht unbedingt bit 7. Es ist nicht unbedingt noch einmal zugewiesen, in der gleichen byte wie du es dir erhofft hast. Mehr Infos hier.
Wenn Sie deaktivieren Polsterung, ist es immer noch schlechte Idee?
Für den größten Teil der Fragen, die von @Lundin sind von der Implementierung abhängig. Ich Stimme die 100% nicht tragbar. Bleibt die Frage: ist dein code, der benötigt wird, um tragbar sein? Eine Menge meiner Arbeit ist es, Treiber für spezifische mikrocontroller, wo ich nachschlagen, wie der compiler pack bits, und es bietet in der Regel eine ausreichende Details, um zu garantieren, die Ergebnisse, die ich will. ABER NUR FÜR EINEN BESTIMMTEN PROZESSOR!
Dies ist eine riskante Möglichkeit zum Zugriff auf bits in Registern. Es könnte funktionieren, für eine version von einem compiler für ein set von compiler-flags, kann aber leicht brechen, was zu schwer, Fehler zu finden.
InformationsquelleAutor DrRobotNinja
Ich denke, das was du fragst ist, wenn Sie ausführen können, eine write-Anweisung auf ein einzelnes bit, ohne zuerst das byte Lesen, dass es in. Wenn ja, dann Nein, das kannst du nicht tun. Hat nichts zu tun mit der C-Sprache, die nur Mikroprozessoren, die nicht über Anweisungen, die einzelnen bits. Sogar im raw-Maschinen-code, wenn Sie wollen ein wenig Sie haben, um das byte zu Lesen, es ist in, ändern Sie das bit, dann schreiben Sie es zurück. Es gibt einfach keinen anderen Weg, es zu tun.
Ja, es nennt sich bit-banding
Cool. Ich vermute, dass der OP ist, Fragen über general-purpose-RAM, obwohl.
Auf ARM-Cortex-M-bit-banding und möglich on-chip-RAM und Peripherie-Register.
Shan nicht downvote, aber es ist einen anderen Weg - viele micros haben, FESTLEGEN und LÖSCHEN von Registern für ports, ich habe es geschrieben als Antwort. OP markiert [embedded], so werde ich davon ausgehen, es ist zutreffend.
InformationsquelleAutor Lee Daniel Crocker
Duplizieren von wie wollen Sie, klar, und setzen Sie ein einzelnes bit und ich werde umbuchen meine Antwort auch als nicht-genannten SET-und CLEAR-Registern noch:
InformationsquelleAutor John U