Hi,
Ich weis nicht ich finde einfach keine Lösung um aus einer Variable die
Bits auszulesen. Vlt stelle i mich auch einfach dumm an.
Hier mal ein Beispiel:
int main(void){
int array[3] = {0x07, 0xEF, 0xA3}
//jetzt möchte ich Beispielsweise aus array[2] die Bits auslesen
}
Wie funktioniert das? Muss i irgend etwas anders machen?
Vielen Dank schon mal im Vorraus.
also bei array[2] is das ja 0xEF
also binär 0b1110 1111
und so möchte ich eben mit den einzelnen bits arbeiten
also ich möchte prinzipiel nur den binären wert der Variable auslesen
Bitte klären: wieviele Bits hat das int?
Dann durch bitweisen Test (Vergleichsoperationen die einzelnen Bits
bestimmen), möglicherweise bringt auch printf etwas.
F. H. schrieb:> also ich möchte prinzipiel nur den binären wert der Variable auslesen
auslesen ist schlecht ausgedrückt.
Aber was du tun kannst:
Du kannst natürlich feststellen, ob ein Bit auf 1 oder auf 0 ist. Und je
nachdem machst du dann etwas anderes. Das funktioniert genau gleich, wie
wenn man von einem Portpin feststellt ob er auf 1 oder auf 0 ist.
Sozusagen ein universeller Mechanismus.
Also. Nicht 'auslesen'.
Sondern: feststellen ob 1 oder 0 und dann darauf reagieren.
F. H. schrieb:> also ich möchte prinzipiel nur den binären wert der Variable auslesen
Es gibt keinen "binären" oder "hexadezimalen" Wert. Es gibt nur einen
Wert.
Was willst du wirklich? Die Binärdarstellung als String, also als
Zeichenkette? Ein einzelnes Bit extrahieren? Etwas anderes?
Okay Vielen Dank
also sollte das theoretisch so funktionieren...oder?
int main(void){
int array[3] = {0x07, 0xEF, 0xA3}
int iPIN1 = array[2] & (1<<0) //müsste ja dann eine 1 sein
int iPIN5 = array[2] & (1<<4) //müsste ja dann eine 0 sein
}
F. H. schrieb:> int iPIN1 = array[2] & (1<<0) //müsste ja dann eine 1 sein
Ja, aber nur zufällig.
> int iPIN5 = array[2] & (1<<4) //müsste ja dann eine 0 sein
Ja. aber auch nur zufällig.
Wenn im Ausgangswert ein 1 Bit gewesen wäre, dann wäre iPIN5 hier nicht
1, sondern 32 (nämlich 1<<4)
Für iPIN1 stimmt das ganze zwar. Aber auch nur deswegen, weil es sich
hier um das Bit 0 handelt, und die Wertigkeit dieses Bits ja nachdem 0
oder 1 ist. Für die restlichen 7 Bits ist das zu kurz gedacht.
Die Grundidee ist allerdings korrekt. Wenn auch, je nachdem wie es dann
weiter geht, unter Umständen nur die halbe Miete.
F. H. schrieb:> okay und wie mach i das dann am besten?
Neben dem, was Stefan angeführt hat:
Am besten - gar nicht.
Wozu auch?
Wozu benötigst du die einzelnen Bits?
Das stellt man zuerst fest und danach entscheidet man, wie man dann an
der verwendenden Stelle auf die Einzelbits zugreift. Je nachdem greift
man nämlich nicht mehr so auf die einzelnen Bits jeder Stelle zu,
sondern benutzt eine etwas andere, abgewandelte Technik. Im Grunde ist
das zwar immer noch ein Maskieren und Verunden, aber man kann da einiges
einsparen, wenn einen nicht interessiert ob da jetzt 0 oder 1 rauskommt,
sondern 0 oder n auch schon reicht.
Weil ich eine Matrix ansteuer und immer einer variable vorgibt welche
leds leuchten müssen. Und eine Variable definiert eine reihe der Matrix.
Ich kann das so aber nicht direkt ausgeben, da i die matrix auf schiebe
registern habe und somit i die signale einzeln durchschiebe.
F. H. schrieb:> Weil ich eine Matrix ansteuer und immer einer variable vorgibt welche> leds leuchten müssen.
Ah siehst du.
Dazu brauchst du den Wert eines Bits nicht in einer Variablen (und schon
gar nicht in einer int Variablen! int willst du nicht benutzen, wenn es
nicht sein muss. Wenn du mit 8 Bit durchkommst, dann nimmst du uint8_t
oder int8_t und nicht das 16-Bit 'int')
1
for(uint8_ti=0;i<8;i++)
2
{
3
if(wert&0x01)
4
Bitist1,machwas
5
else
6
Bitist0,machwas
7
8
wert>>=1;
9
}
denn was du auf keinen Fall möchtest, ist ein
1
....&(1<<i)
in irrgend einer Form. Denn das ist ein teure Operation. Da schiebst du
lieber einen Wert sukzessive um jeweils 1 Stelle nach rechts und testest
immer auf das 0-te Bit
(oder schieben nach links und testen auf das 7-te Bit, wenn die
Reihenfolge anders rum sein soll)
F. H. schrieb:> Kann i das dann auch direkt so machen?
Das weiß ich nicht, ob du die Programmteile, die ich jetzt hier nicht
ausgeführt habe, wie zb die Ansteuerung der Schieberegister, alleine
hinkriegst.
Aber die Abarbeitung der einzelnen Bits in einem Byte, welches in 'wert'
steht, die kannst du so machen - drum hab ich das ja aufskizziert, wie
man das in so einer konkreten Situation macht.
F. H. schrieb:> Kann i das dann auch direkt so machen?
ach jetzt seh ichs erst
> if( wert & i )
Nein. Völlig falsch.
Wozu soll das gut sein?
Du scheinst nicht begriffen zu haben, was das Konzept ist.
Anstatt sich jeweils ein eigenes 'Fenster' zu machen, mit dem man einen
Blick auf das i-te Bit erhascht, dreht man den Spiess um. Man macht 1
immer gleiches Fenster und schiebt die Bits unter dem "Fenster" durch.
Das ist nämlich für den µC einfacher, weil die Erzeugung des "Fensters"
für einen AVR eine aufwändige Sache ist.
Im Endeffekt kommt aber beides aufs gleiche raus.
Ist der Speicher so knapp?
ich würde lieber 1 Byte für einen Matrixpunkt nehmen.
Das Bit hin und hergeschiebe ist zwar interessant, und manchmal
sinnvoll.
Aber jeden Matrixpunkt mit einem Namen ansprechen zu können, ist für
mich die einfachere Lösung. Dann bracht man nicht jedesmal so tolle
Bitmanipulationen.
F. H. schrieb:> Sry bin in dieser Materie noch nicht ganz so durchgestiegen.> Deswegen frag ich ja auch nach.
Das Problem ist eigentlich, dass das hier noch der einfachste Teil der
Ansteuerung einer Matrix ist.
Eine LED-Matrix ist nun mal kein Einsteigerprojekt, auch wenn es viele
immer wieder dafür halten (und mir rätselhaft ist, was an einer kleinen
LED-Matrix so toll sein soll - aber das muss jeder für sich entscheiden)
Damit es Dir später nicht noch auf die Füße fällt:
F. H. schrieb:> also bei array[2] is das ja 0xEF
Nein. Gemäß Deines Eröffnungsbeitrags ist der Wert von array[2] gleich
0xA3.
F. H. schrieb:> Allerdings kommt immer 0 raus
Woher weist Du das?
> if(wert & 0x01)
Wo kommt denn plötzlich die Variable "wert" her?
Du musst wohl etwas mehr Code zeigen.
Möglicherweise währe es einfacher, wenn du die SPI Hardware benutzt für
das Schieberegister. Dann kannst du nämlich deine ganze 8-Bit Variable
mit dpi_fast_shift(deine_variable); übergeben.
Aus deinem Code werde ich leider überhaupt nicht schlau, aber hier die
simpelste Variante (nicht optimiert) wie ich es machen würde:
F. H. schrieb:> Sry so funktioniert es schon.> Nur sobald der Wert über einem bit ist> klappt es nicht mehr
Dann zeig halt mal den RICHTIGEN Code.
Dann hilft dir auch jemand, all die kleinen blöden Fehler zu
eliminieren, die du eingebaut hast.
Sean Goff schrieb:> Aus deinem Code werde ich leider überhaupt nicht schlau, aber hier die> simpelste Variante (nicht optimiert) wie ich es machen würde:
Das ist doch Quatsch
Wenn du mit einer Schleife nicht umgehen kannst, dann lass es und red
nicht Anfängern so einen Unsinn ein.
SPI Hardware einzusetzen ist grundsätzlich ok.
Aber auch die 'händische' Ausgabe zu Fuss ist keine Raketentechnik und
eine derartige Funktion ist in weniger als 14 Zeilen Code abgehandelt
1
voidoutputByte(uint8_twert)
2
{
3
for(uint8_ti=0;i<8;i++)
4
{
5
if(wert&0x01)
6
ein1BitaufdieDatenleitungschalten
7
else
8
ein0BitaufdieDatenleitungschalten
9
10
Clockauf1
11
Clockauf0
12
13
wert>>=1;
14
}
15
}
(die Portoperationen müssen noch ausformuliert werden)
Bei einer Schieberegisterkette bestehend aus 595 Schieberegistern wird
dann hinten nach, nachdem alle Bytes ausgegeben worden sind und somit
die Schieberegister neu befüllt wurden, noch der Puls auf RCLK
ausgegeben, damit die Schieberegister den neuen Inhalt auch auf die
Ausgänge durchschalten.
SPI Hardware dafür lass ich mir gerne einreden. Aber eigentlich ist die
ganze Sache so simpel, dass die jeder in 10 Minuten programmieren können
muss. Und zwar auch dann, wenn ich ihn morgens um 4 aus dem Bett hole.