Forum: Mikrocontroller und Digitale Elektronik AVR: Pinstatus in Byte schreiben


von lightninglord (Gast)


Lesenswert?

Hallo Zusammen,

ich hab ein kleines programmiertechnisches Problem: Das ganze ist eine 
art SPI-Verschnitt ( leider ist der HWSPI schon mit dem Funkmodul 
beschäftigt . Ich möchte bei jedem LOW auf dem CK den DA einlesen und in 
das Bit an der j-ten stelle im digi_data-Array im i-ten Byte schreiben. 
So hier mein Code dazu:
1
for (j=0; j<8; j++)
2
    {
3
      while (DIGI_PIN & (1<<DIGI_CK));            //Warte auf LOW
4
      
5
      digi_data[i] |= (DIGI_PIN && (1<<DIGI_DA)) & (1<<j);  //Schreibe PIN in Bit j
6
7
      
8
      while (!(DIGI_PIN & (1<<DIGI_CK)));            //Warte auf HIGH
9
10
    }

Leider funktioniert es nicht, ich hab schon ein bisschen mit dem 
Simulator rungespielt aber ich bekomme einfach nichts in meine Bytes 
geschrieben. Könnt ihr mir helfen, ich finde meinen Denkfehler leider 
nicht.

Grüßle

lightninglord

von Karl H. (kbuchegg)


Lesenswert?

lightninglord schrieb:

>       digi_data[i] |= (DIGI_PIN && (1<<DIGI_DA)) & (1<<j);  //Schreibe

                                  **
Das ist ein logisches Und. Du willst eine binäre Und Verknüpfung des Pin 
Inhalts mit 1<<DIGI_DA   ->  & verwenden

Das nächste Problem ist, dass dieses nicht 0 oder 1 ergibt, sondern 0 
bzw. 1<<DIGI_DA, je nach Zustand das Pins.

Versuch dich nicht selbst auszutricksen, indem du möglichst komplizierte 
Verknüpfungen machst. Oft ist der klarste Weg auch der Beste

    if( DIGI_PIN & ( 1<<DIGI_DA) )
      digi_data[i] |= (1<<j);

PS: Du möchtest das variable Schieben der 1 mit j auf jeden Fall weg 
haben. Die Operation ist nämlich ziemlich teuer und man kann sie ganz 
leicht umgehen.

von lightninglord (Gast)


Lesenswert?

>PS: Du möchtest das variable Schieben der 1 mit j auf jeden Fall weg
>haben. Die Operation ist nämlich ziemlich teuer und man kann sie ganz
>leicht umgehen.

Hätteste mir nen kleinen Tip, mein C ist etwas eingerostet.

von Karl H. (kbuchegg)


Lesenswert?

lightninglord schrieb:
>>PS: Du möchtest das variable Schieben der 1 mit j auf jeden Fall weg
>>haben. Die Operation ist nämlich ziemlich teuer und man kann sie ganz
>>leicht umgehen.
>
> Hätteste mir nen kleinen Tip, mein C ist etwas eingerostet.

Gesehen über die Schleife, was ergibt denn i<<j wenn sich j langsam von 
0 bis 8 aufbaut.

   00000001
   00000010
   00000100
   00001000
   00010000
   00100000
   01000000
   10000000

Nun muss man das aber nicht über 1<<j jedesmal neu errechnen. Es gneügt 
doch, wenn man sich vor der Schleife eine Maske mit einer 1 zurechtlegt 
und diese Maske in jedem Schleifendurchlauf um 1 nach links schiebt.
1
   uint8_t mask = 0x01;
2
3
   digi_data[i] = 0;
4
   for( j = 0; j < 8; ++j ) {
5
     if( DIGI_PIN & ( 1<<DIGI_DA) )
6
       digi_data[i] |= mask;
7
8
     mask = mask << 1;
9
   }

und schon ist aus dem variablen Schieben ein konstantes Schieben um 
jeweils 1 geworden. (Ganz abgesehen davon, dass das dann in Summe 
weniger Schiebevorgänge sind :-)

von lightninglord (Gast)


Lesenswert?

Dank dir, das war so einfach, da bin ich jetzt ned drauf gekommen, hab 
mich schon in struckt anfangen Einzulesen, wird wohl Zeit Mittag zu 
machen ;-)

Danke nochmals.

Grüßle

von Karl H. (kbuchegg)


Lesenswert?

(Alternativ könnte man auch immer nur das unterste Bit in digi_data[i] 
setzen und dafür digi_data[i] um jeweils 1 Stelle nach links schieben)
1
   digi_data[i] = 0;
2
   for( j = 0; j < 8; ++j ) {
3
     digi_data[i] = digi_data[i] << 1;
4
     if( DIGI_PIN & ( 1<<DIGI_DA) )
5
       digi_data[i] |= 0x01;
6
   }

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.