Ich möchte gerne folgendes Bit-Muster mit einer Tasteneingabe hochzählen und mit einer anderen taste runterzählen: 0000 0000 0001 0000 0010 0000 0011 0000 und das gleiche mit: 0000 0000 0000 0100 0000 1000 0000 1100 Wenn das letzte Bitmuster erreicht ist und man schaltet weiter soll wieder von vorne begonnen werden. Wie stell ich das am einfachsten an? Es sollen ja immer nur 2 Bits fortlaufend geändert werden. Soll ich hier binär oder doch lieber Hex zählen? -> Wäre jetzt Profimäßig geklärt...
Gast
#4665993
Lokus P. schrieb: > Soll ich hier binär oder doch lieber Hex zählen? Und was macht das an Unterschied?
Gast
#4665994
Lokus P. schrieb: > Soll ich hier binär oder doch lieber Hex zählen? Ich stehe vor einem ähnlichen Problem. Ich hoffe ihr könnt mir weiterhelfen. Soll ich jetzt Butter oder Margarine aufs Brot tun?
Also ob mir das hier jetzt weiterhelfen würde.
Gast
#4665997
Frickelfritze schrieb: > Soll ich jetzt Butter oder > Margarine aufs Brot tun? Das ist falsch. Es muss "Butter oder Butter" heißen. Die Zahlendarstellung im Programm spielt keine Rolle, wenn die Variable selbst binär ist. (Also int, uint8_t, ...)
Ok, hätten wir mal die erste Frage geklärt. Wie siehts jetzt mit dem Rest aus?
Dem Prozessor ist es völlig wurscht. Binär oder Hexadezimal sind nur verschiedene Darstellungsarten. Die Daten und die Rechenoperationen, die im Programm ausgeführt werden, sind exakt die selben. Daher nimm das, was besser lesbar ist. Da du uns die Sprache verheimlichst, kann man da wenig Tipps geben. Lokus P. schrieb: > Wie siehts jetzt mit dem Rest aus? Welchem Rest?
Lokus P. schrieb: > Ok, hätten wir mal die erste Frage geklärt. Wie siehts jetzt mit dem > Rest aus? Mit einer AND-Verknüpfung (C-Operator: &) kannst Du beliebige Bits auf 0 zwingen, also z.B. ergibt 1011 0101 & 0011 1100 --------- 0011 0100
Gast
#4666045
Lokus P. schrieb: > Wie stell ich das am einfachsten an? zB. etwa so:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Wie man bits setzt weiß ich auch wie man zählt, aber wie genau definiere ich das nur ein bestimmter Bitbereich hochgezählt werden soll.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Gast
#4666064
"wie genau definiere ich das nur ein bestimmter Bitbereich hochgezählt werden soll?" Z.B. indem du als Zähleinheit 16 oder 4 addierst anstatt 1...
W.A. schrieb: > p = (p++) & 0x03; wohl eher p = (++p) & 0x03;
Thomas E. schrieb: > W.A. schrieb: >> p = (p++) & 0x03; > > wohl eher p = (++p) & 0x03; Wie in einem Thread nebenan letztens ausführlich diskutiert, ist beides nicht zulässig, da das Verhalten in C undefiniert ist. Es muss heißen:
1 | |
Alternativ:
1 | |
2 | |
Rolf M. schrieb: > Wie in einem Thread nebenan letztens ausführlich diskutiert, ist beides > nicht zulässig, da das Verhalten in C undefiniert ist. Es muss heißen: Unabhängig davon, daß ich hier auch (p+1) bevorzugen würde (weil "schöner"), sehe ich an (++p) aber weder ein undefiniertes Verhalten, noch warum es unzulässig sein soll!? Auch (p++) ist zulässig und definiert, führt hier bei "p = (p++)" aber nicht zur Veränderung der Variablen p.
Was soll Ausgabe1 darstellen?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
oder wie?
Gast
#4666194
Wieso nicht einfach im ersten Fall 16 als Inkrement/Dekrement nehmen und im zweiten Fall 4
Gast
#4666199
lustig wie das hier völlig entgleist????
eher armselig.
Gast
#4666218
..eher armselig ist die Fragestellung! Die stellt kein Fünfjähriger mehr. Nimm mal ein Blatt Papier und nen Bleistift. Auf Tastendruck erhöht sich eine Variable jeweils von Null um den Wert 16. Also 0,16,32,48. Bei 48 soll es umgekehrt laufen. Wer das Problem löst, bekommt einen Nobelpreis. Haha
Lokus P. schrieb: > Was soll Ausgabe1 darstellen? > ... > oder wie?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Die magischen Zahlen kann man besser als SHIFT und MASK einmal festlegen, via #define oder static const (oder constexpr, wenn man dessen Sprache spricht) Der Zähler könnte natürlich auch außerhalb des OUT_PORT leben, als globale Variable @Db: Einfach nur 16 draufaddieren funktioniert natürlich nur, wenn man kein Problem mit den Überlauf des Zählers auf das 3.Bit hat. Besser geht das mit C++ (mit avr-gcc5.3),da bin ich gerade am Erkunden von C++11/14. Mit etwas variadic template kann man die Bits, die man hoch/runter zählen will in jeder beliebigen Reihenfolge auf jedem vorhandenen PORT verteilen.
Thomas E. schrieb: > Rolf M. schrieb: >> Wie in einem Thread nebenan letztens ausführlich diskutiert, ist beides >> nicht zulässig, da das Verhalten in C undefiniert ist. Es muss heißen: > > Unabhängig davon, daß ich hier auch (p+1) bevorzugen würde (weil > "schöner"), sehe ich an (++p) aber weder ein undefiniertes Verhalten, > noch warum es unzulässig sein soll!? Nicht das (++p) alleine, sondern in Kombination mit der Zuweisung. > Auch (p++) ist zulässig und definiert, führt hier bei "p = (p++)" aber > nicht zur Veränderung der Variablen p. Es fürt zu undefiniertem Verhalten laut ISO C, da die Variable p zweimal beschrieben wird, ohne dass ein Sequenzpunkt dazwischen liegt. Aber wie gesagt, das wurde letztens schon ausführlichst diskutiert.
Gast
#4666266
Lokus P. schrieb: > eher armselig. Armselig ist deine Frage. Jeder mit Minimal-Eigenintelligenz würde sich schämen, sie überhaupt gestellt zu haben... Denn sie beweist: 1) Du hast keine Ahnung von binärer Logik. 2) Du hast keine Ahnung von der Programmiersprache, die du verwendest. Damit: Du tust etwas, wozu dir sämtliche essentiellen Grundlagen fehlen. Mehr noch: Dir ist nicht einmal klar, dass diese Grundlagen essentiell sind und dass sie dir fehlen. Klar: dann muss natürlich jeder Hinweis auf diesen Problemkreis aus deiner Sicht einer Beleidigung gleichkommen. Ist aber keine... Es ist einfach so: ein wirklich Doofer kann einfach nicht erkennen, dass er doof ist...
Carl D. schrieb: > Lokus P. schrieb: >> Was soll Ausgabe1 darstellen? >> ... >> oder wie? > void right() > { > int p; // tmp, Zähler selbst ist Teil von OUT_PORT > > p = (OUT_PORT>>4) & 3; // 3 ist max 2Bit, 4 ist Ausgabeposition > P = (p+1) % 4; // 0..3 > > OUT_PORT = OUT_PORT & ~(3<<4) // Bit 4..5 "frei machen" > | (P<<4); // Zähler wieder einfügen > ... > } > > Die magischen Zahlen kann man besser als SHIFT und MASK einmal > festlegen, via #define oder static const (oder constexpr, wenn man > dessen Sprache spricht) > > Der Zähler könnte natürlich auch außerhalb des OUT_PORT leben, als > globale Variable > > @Db: > Einfach nur 16 draufaddieren funktioniert natürlich nur, wenn man kein > Problem mit den Überlauf des Zählers auf das 3.Bit hat. > > Besser geht das mit C++ (mit avr-gcc5.3),da bin ich gerade am Erkunden > von C++11/14. Mit etwas variadic template kann man die Bits, die man > hoch/runter zählen will in jeder beliebigen Reihenfolge auf jedem > vorhandenen PORT verteilen. Das funktioniert doweit, danke. Aber warum bekomme ich diesen Warnhinweis: ../main.c:104: warning: suggest parentheses around arithmetic in operand of | bei der Zeile: OUT_PORT = OUT_PORT & ~(3<<4) | (p<<4);
Gast
#4666298
>Aber warum bekomme ich diesen Warnhinweis:
Weil da Klammern fehlen.
Gast
#4666311
c-hater schrieb: > Es ist einfach so: ein wirklich Doofer kann einfach nicht erkennen, dass > er doof ist... ...und ein kaltschnäuziger, arroganter Mensch kann einfach nicht erkennen, daß er NICHT der Nabel der Welt ist. Auch wenn ich dir hier in der Sache völlig recht gebe, aber deine Ausdrucksweise macht deiner Mutter klar, daß sie mit deiner Erziehung auf ganzer Linie völlig versagt hat.
Gast
#4666317
> Aber warum bekomme ich diesen Warnhinweis: > > ../main.c:104: warning: suggest parentheses around arithmetic in operand > of | > > bei der Zeile: OUT_PORT = OUT_PORT & ~(3<<4) | (p<<4); Weil es sehr schlechter Stil ist, bei Binäroperatoren Klammern wegzulassen. Deren Präzedenz ist teilweise unintuitiv und führt ohne Klammern schnell zu Fehlern. Ich würde übrigens in zwei getrennten globalen Variablen zählen, und aus den aktuellen Zählerständen dann die Ausgabe auf den Port zusammensetzen.
holger schrieb: >>Aber warum bekomme ich diesen Warnhinweis: >> ../main.c:104: warning: suggest parentheses around arithmetic in operand >> of | >> >> bei der Zeile: OUT_PORT = OUT_PORT & ~(3<<4) | (p<<4); > Weil da Klammern fehlen. Ja, aber nicht wie's der Compiler vorschlägt, denn erst muß man die Bits maskieren (&) und dann den neuen Wert einfügen (|). @Lokus: Schreib es so:
1 | |
dann versteht es der GCC (und vielleicht auch sonst noch wer)
Rolf M. schrieb: > Es fürt zu undefiniertem Verhalten laut ISO C, da die Variable p zweimal > beschrieben wird, ohne dass ein Sequenzpunkt dazwischen liegt. > Aber wie gesagt, das wurde letztens schon ausführlichst diskutiert. Sorry, habe diese Diskussion offenbar wohl nicht verfolgt, und weiß auch nicht, wo/wie ich danach suchen soll. Ist es nicht so, daß bei einer Zuweisung zuerst der Ausdruck rechts vom "=" ausgewertet wird, und dann der Wert des Ausdrucks der Variablen zugewiesen wird? Da sehe ich jedenfalls keinen Raum für Undefiniertes!
Das ganze sieht jetzt so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
Da ist jedoch noch ein Fehler drinn. Wenn ich die Funktion down() aufrufe, werden irgendwann Bit 4 und 5 auch gesetzt.
Gast
#4666351
Lokus P. schrieb: > d = (d-1) % 4; wenn d=0 ist, dann wird d negativ. Dann kommt Unsinn bei, nächsten schritt Unsinn raus.
Thomas E. schrieb: > Rolf M. schrieb: >> Es fürt zu undefiniertem Verhalten laut ISO C, da die Variable p zweimal >> beschrieben wird, ohne dass ein Sequenzpunkt dazwischen liegt. >> Aber wie gesagt, das wurde letztens schon ausführlichst diskutiert. > > Sorry, habe diese Diskussion offenbar wohl nicht verfolgt, und weiß auch > nicht, wo/wie ich danach suchen soll. Ich meinte diese hier: Beitrag "fragezeichen operator may be undefined" Am Ende von Beitrag "Re: fragezeichen operator may be undefined" hab ich auch nochmal explizit hingeschrieben, was dazu in der ISO-C-Spezifikation steht. Die dort angegebenen Beispiele verdeutlichen, dass es genau um solche Fälle geht. In der Diskussion haben das einige auch nicht eingesehen, weil sie sich nicht vorstellen können, warum da was schiefgehen sollte. Das ändert aber nichts daran. Solche undefinierten Konstrukte hinzuschreiben, ist wie mit abgefahrenen Reifen rumfahren und zu ignorieren, dass das gefährlicher und außerdem verboten ist, weil ja noch nie was passiert ist. > Ist es nicht so, daß bei einer Zuweisung zuerst der Ausdruck rechts vom > "=" ausgewertet wird, und dann der Wert des Ausdrucks der Variablen > zugewiesen wird? Das schon, aber nicht definiert ist, wann die Nebeneffekte (also das Schreiben in die Variable) abgeschlossen ist.
Das mit dem Modulo muß man natürlich für Zähler bis 2hochN -1 nicht machen.
1 | |
2 | |
3 | |
4 | |
5 | |
Damit zählt man Modulo 4 hoch/runter. Ich habe mit Absicht stehen gelassen, wie es zur magischen Zahl 3 kommt. In konkreten Programm sollt man da #define's benutzen (oder bessere Nachfolger). Denn eventuell will man mal 3Bit Zähler, die auf 0..2 und 5..7 am Port erscheinen sollen, umstellen. Was bedeutet dann nochmal 2, 3 und 4?
noch eine Frage dazu. ich rufe aus der Function noch eine Function auf: reset() Das erzeugt mir eine Warnung: ../main.c:75: warning: implicit declaration of function 'reset' Die könnte man zwar ignorieren, aber wie macht man es richtig? Drauf verzichten?
Gast
#4666408
Lokus P. schrieb: > Die könnte man zwar ignorieren, aber wie macht man es richtig? Man könnte es richtig machen und sie nicht ignorieren. Denkst du, die Warnung ist ein Scherz? Sieh mal in einem c-Buch nach oder bemühe eine Suchmaschine. Du bist sicherlich nicht der erste, der diese Warnung bekommt, also findest du die Auflösung sicher bei einer Suchmaschine...
Rolf M. schrieb: > Ich meinte diese hier: ... Danke! Habe inzwischen auch noch selbst ein bisschen gegoogled. Dachte, eine Zuweisung wäre praktisch auch schon ein Sequenzpunkt, ist es aber dann wohl doch nicht. Man lernt halt nie aus... :)
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.