Ich möchte gerne 8 Signale auswerten und Abweichungen über 8 LED's an
PORT B ausgeben.
Um mir mit meinem AVR ATmega die Arbeit leicht zu machen, möchte ich
durch eine Schleife und Bitschieben die Ausgabe "vorkonfigurieren". Der
Ansatz ist unten aufgelistet. Kann ich das so machen, sind meine
Gedanken richtig?
1
Ausgabe=0;
2
for(i=1;i<=8;i++)
3
{
4
ifistwert[i]>=sollwert
5
Ausgabe|=(1<<i);
6
}
7
PortB=Ausgabe;
Wenn meine Abweichungen jetzt bei Wert 1, 3 und 6 sind sollen
entsprechend die LED's 1,3 und 6 leuchten. Mein Ausgabe-
Zwischenspeicher ist 0 und es soll die "1" um i Stellen in den Zwischen
speicher geschoben werden:
- eine "1" um eine Stelle nach links (Ausgabe = 0b 0000 0001) mit (1<<1)
- eine "1" um drei Stellen nach links (Ausgabe = 0b 0000 0101) mit
(1<<3)
- eine "1" um sechs Stellen nach links (Ausgabe = 0b 0010 0101) mit
(1<<6)
Danach möchte ich den Zwischenspeicher an die LED's ausgeben mit PortB =
0b 0010 0101
Ist das so korrekt?
M.B. wrote:
> - eine "1" um eine Stelle nach links (Ausgabe = 0b 0000 0001) mit (1<<1)
Nö, das was da binär steht ist (1 << 0), also eine 1, die um null
Stellen nach links geschoben ist!
> - eine "1" um drei Stellen nach links (Ausgabe = 0b 0000 0101) mit> (1<<3)
(1 << 3) wäre 0b00001000...
Ah ja richtig. Die "Grundstellung" ist ja 0b 0000 0001 und dann die
Stellen der Verschiebung.
Danke für den Tipp, hatte ich nicht bedacht. Guter hinweis.
Aber hierzu:
>> - eine "1" um drei Stellen nach links (Ausgabe = 0b 0000 0101) mit>> (1<<3)>(1 << 3) wäre 0b00001000...
wie du im Code siehst ist das ganze ja verodert mit "|=" da soll der
Wert von vorher ja beibehalten werden und die um drei Stellen
verschobene "1" dazugerechnet werden.
M.B. wrote:
> Ist das so korrekt?
Im Prinzip passt das schon so. (Nach der Korrektur, dass i bei 0 anfängt
und nicht bei 1)
Das einzige, was du bedenken solltest: Die Operation 1 << i ist für
einen AVR ziemlich aufwändig, weil sie nicht in einem Schritt gemacht
werden kann, sondern der Compiler muss das seinerseits als Schleife
implementieren, bei der die 1 jeweils i mal um 1 geschoben wird. (Ausser
natürlich: der Optimizer des Compilers ist seeeeehr gut. Da würde ich
aber nicht drauf wetten). Da dein i aber schön aufsteigend durchlaufen
wird, kannst du das auch selber etwas besser formulieren
1
Ausgabe=0;
2
Mask=1;
3
4
for(i=1;i<=8;i++)
5
{
6
if(istwert[i]>=sollwert)
7
Ausgabe|=Mask;
8
Mask=Mask<<1;
9
}
10
11
PortB=Ausgabe;
PS: Bist du sicher, dass dein Array istwert wirklich von der Länge 9
ist? Ansonsten greifst du auf das Array 'out of Bounds' zu. Ein Array
int istwert[8];
besitzt 8 Elemente. Diese haben die Indizes: 0, 1, 2, 3, 4, 5, 6, 7
(und keinen Index 8!). Zähl nach, es sind genau 8 Elemente.
Die übliche for-Schleife, um so ein Array abzuabeiten lautet daher
for( i = 0; i < 8; i++ )
sie beginnt bei 0, und in der Vergleichsbedingung (welche immer auf
"kleiner" lautet), steht die Arraygröße und nicht der höchste Index.
Ich würde daher wetten, dass dein Code eigentlich so aussehen sollte
Hallo Karl heinz, Danke für die Info.
Ich bin immer froh für Tipps zur Codeoptimierung.
Mein Array ist wirklich von der Länge 9, wobei ich die 0 leer lasse.
(Platz habe ich genug)
Weil ich es einfach nicht so umständlich finde.Ich habe 1 bis 8 Signale
durchlaufe die Schleife 1- 8 mal und die LED's 1 bis 8 leuchten. Für
mich wäre es dann irritierend wenn ich dann in den Speicherzellen 0-7
die Werte speicher. War jetzt der Wert 4 für die vierte oder fünfte LED
oder Signal. Oder war es doch das dritte?
So kann ich mir einfach merken in Zelle 4 steht das Signla des 4.
Signals und ist für LED 4. Zelle 0 kann ich zur Not mit anderen Sachen
benutzen falls erforderlich, für Summen oder zur Korntrolle oder für
Zwischenwerte.
Mein Code dafür würde dann so aussehen:
@M.B.:
Du solltest Dir dringend die in der Technik übliche Zählweise
angewöhnen, sonst kommst Du irgendwann wirklich durcheinander! Bei
solchen Zusammenhängen, bei denen es um Bits in Variablen oder Registern
geht, fängt die Zählung grundsätzlich bei 0 an, nicht bei 1. Auch Deine
LEDs solltest Du von 0 bis 7 durchnummerieren, schließlich heißen die
Portpins auch PORTx0...7 und nicht anders. Wenn Du das nicht
verinnerlichst, wirst Du irgendwann massive Probleme bekommen. Das mit
dem 1<<1 oben wäre Dir nämlich auch nicht passiert, wenn Du daran
gedacht hättest...
Hallo Johannes,
ich werde darüber nachndenken. Hört sich schlüssig an. Besser frühzeitig
umdenken als zu spät - aber für mich ist es halt noch eher umständlich.
Aber ich werde mich bemühen - versprochen!
M.B. wrote:
> ich werde darüber nachndenken. Hört sich schlüssig an. Besser frühzeitig> umdenken als zu spät
Genau das ist der Punkt. Nicht erst was falsches angewöhnen.
> - aber für mich ist es halt noch eher umständlich.
Nun, das sind viele Dinge auf den ersten Blick. Nur werden sie noch
komplizierter, wenn man versucht, mit irgendwelchen Verrenkungen drumrum
zu kommen...
Auch ist es deinem Compiler ziemlich egal, wo du für dich den ersten
Index in ein Array siehst. Spätestens bei Strings kocht der sowieso sein
eigenes Süppchen und lässt das char Array in dem ein String gespeichert
ist beim Index 0 anfangen.
char Test = "Hello world";
das 'H' ist nun mal an Position Test[0].
Auch vereinfachen sich viele Index-Berechnungsvorgänge, wenn man den
ersten Index als 0 annimmt. Das ganze ist also nicht nur akademisch
sondern hat durchaus einen ernsten Hintergrund.
Bsp: Du brauchst eine Umsetztabelle, die Zahlenwerte von 80 bis 83
(jeweils inklusive) in neue Zahlen umsetzt.
80 -> 256
81 -> 123
82 -> 205
83 -> 78
Wie ist der übliche Ansatz:
char Table[] = { 256, 123, 205, 78 };
int NewValue = Table[ OldValue - 80 ];
Wenn OldValue den Wert 80 hat, dann ergibt OldValue - 80 die 0. Also den
Index des ersten Eintrags.
Wenn du dein System konsistent durchziehen willst, dann müsstest du
schreiben
char Table[] = { 0, 256, 123, 205, 78 };
int NewValue = Table[ OldValue - 80 + 1 ];
und das gibt es oft: Wenn Indizes berechnet werden müssen, sind die
Formeln einfacher, wenn der erste Index die 0 hat.
Karl heinz Buchegger wrote:
> char Table[] = { 256, 123, 205, 78 };
Hmm, mit char wird das aber nix...
(Wenn Du es korrigiert hast, kannste dieses dann gegenstandslose Posting
löschen...)
Johannes M. wrote:
> Karl heinz Buchegger wrote:>> char Table[] = { 256, 123, 205, 78 };> Hmm, mit char wird das aber nix...
LOL.
Danke für die Korrektur.
> (Wenn Du es korrigiert hast, kannste dieses dann gegenstandslose> Posting löschen...)
Kanns im Original nicht mehr korrigieren. Daher bleibt auch dein absolut
korrekter Fehleraufschrei da :-)