Forum: Mikrocontroller und Digitale Elektronik Bit in Byte mit Schleife setzen/abfragen


von Markus P. (sebastianwurst)


Lesenswert?

Hallo,
ich habe eine For-Schleife mit der ich je nach Status eines Arrays 
(ausgang _status[i]) ein Bit in der Variable  (StatusPortx) setzen will. 
Leider klappt das nur für das erste Byte (StatusPort1) Kann mir einer 
sagen was ich da falsch mache?
1
 uint8_t StatusPort1,StatusPort2,StatusPort3,StatusPort4,StatusPort5,StatusPort6,StatusPort7,StatusPort8,StatusPort9,StatusPort10,
2
    StatusPort11,StatusPort12,StatusPort13,StatusPort14,StatusPort15,StatusPort16 = 0;
1
    for (uint16_t i = 0; i < 128; i++)
2
    {
3
      ausgaenge_status[i] = (ausgaenge_status[i] ^ ausgaenge_schalten[i]);
4
      ausgaenge_schalten[i] = 0;    
5
      
6
      if (ausgaenge_status[i]) 
7
      {
8
        if      (i< 8)  StatusPort1 |= ( 1 << i );
9
        else if      (i< 16) StatusPort2 |= ( 1 << i );
10
        else if      (i< 24) StatusPort3 |= ( 1 << i );
11
        else if      (i< 32) StatusPort4 |= ( 1 << i );      
12
        else if      (i< 40) StatusPort5 |= ( 1 << i );  
13
        else if      (i< 48) StatusPort6 |= ( 1 << i );  
14
        else if      (i< 56) StatusPort7 |= ( 1 << i );  
15
        else if      (i< 64) StatusPort8 |= ( 1 << i );  
16
        else if      (i< 72) StatusPort9 |= ( 1 << i );  
17
        else if      (i< 80) StatusPort10 |= ( 1 << i );  
18
        else if      (i< 88) StatusPort11 |= ( 1 << i );  
19
        else if      (i< 96) StatusPort12 |= ( 1 << i );  
20
        else if      (i< 104) StatusPort13 |= ( 1 << i );  
21
        else if      (i< 112) StatusPort14 |= ( 1 << i );  
22
        else if      (i< 120) StatusPort15 |= ( 1 << i );  
23
        else if      (i< 128) StatusPort16 |= ( 1 << i );
24
      }        
25
      else
26
      {
27
        if      (i< 8) StatusPort1 &= ~(1 << i);
28
        else if (i< 16) StatusPort2 &= ~(1 << i);
29
        else if (i< 24) StatusPort3 &= ~(1 << i);
30
        else if (i< 32) StatusPort4 &= ~(1 << i);
31
        else if (i< 40) StatusPort5 &= ~(1 << i);
32
        else if (i< 48) StatusPort6 &= ~(1 << i);
33
        else if (i< 56) StatusPort7 &= ~(1 << i);
34
        else if (i< 64) StatusPort8 &= ~(1 << i);
35
        else if (i< 72) StatusPort9 &= ~(1 << i);
36
        else if (i< 80) StatusPort10 &= ~(1 << i);
37
        else if (i< 88) StatusPort11 &= ~(1 << i);
38
        else if (i< 96) StatusPort12 &= ~(1 << i);
39
        else if (i< 104) StatusPort13 &= ~(1 << i);
40
        else if (i< 112) StatusPort14 &= ~(1 << i);
41
        else if (i< 120) StatusPort15 &= ~(1 << i);
42
        else if (i< 128) StatusPort16 &= ~(1 << i);
43
                
44
      }
45
    } // For Schleife Ende

Das Status Bit frage ich dann so ab:
1
if (StatusPort6&0b00000001) {......
2
if (StatusPort6&0b00010000) {......

von Noname (Gast)


Lesenswert?

Offen gesagt habe ich den Eindruck, das Du mit dem Schlachtschiff ne 
Pfütze überwinden willst. Wenn Du mal genauer erklärst worum es geht, 
kann man das sicher noch wesentlich einfacher erledigen.

Aber meine Glaskugel sagt mir sowas wie:
1
        else if      (i< <y>) StatusPorty<x> |= ( 1 << (i%8) );

von Wolfgang (Gast)


Lesenswert?

Erste Maßnahme wäre, deine StatusPortX in ein Array StatusPort[] zu 
packen und dann statt der if/else if-Kette direkt über das High-Byte von 
i zu adressieren.

von PittyJ (Gast)


Lesenswert?

for (uint16_t i = 0; i < 128; i++)
    ...
          StatusPort1 |= ( 1 << i );


es wird i um 127 Stellen nach rechts geschoben. Das kann kein Prozessor 
mehr darstellen, weil die Register oft nur 32 Bit breit sind.

und das Ziel hat nur 8 Bit. Da ist spätestens beim 9ten Bit Schluss mit 
einer Veränderung.


Man sollte evtl ein Array der statusports nehmen

uint8_t Statusports[16].

und dann mit
Statusports[ Port / 8] |= 1<<( Port % 8)
das Bit setzen. (oder so ähnlich)

von Markus P. (sebastianwurst)


Lesenswert?

PittyJ schrieb:
> es wird i um 127 Stellen nach rechts geschoben. Das kann kein Prozessor
> mehr darstellen, weil die Register oft nur 32 Bit breit sind.

Da war mein Denkfehler... Danke schonmal... Jetzt überlege ich wie ich 
es am besten hin bekomme, also ein Array StatusPort[x] will ich nicht 
machen, es soll schone jeweils ein Byte sein.

von Tom R. (Gast)


Lesenswert?

Markus P. schrieb:
> Da war mein Denkfehler... Danke schonmal... Jetzt überlege ich wie ich
> es am besten hin bekomme, also ein Array StatusPort[x] will ich nicht
> machen, es soll schone jeweils ein Byte sein.

Das mußt du jetzt mal erklären. Was bringt das für einen Vorteil?

von Noname (Gast)


Lesenswert?

Ich denke auch das es Dir Vorteile bringt wenn Du das Problem mal 
beschreibst, so das wir Dir was dazu sagen können.

Solche ellenlangen Listen von Parametern oder bedingten Anweisungen mit 
nur numerisch unterschiedlichen Bedingungen und in den abhängigen 
Anweisungen sind fast immer ein Hinweis darauf, das das Konzept einen 
bedeutenden Denkfehler enthält.

von Markus P. (sebastianwurst)


Lesenswert?

Weil ich eine Funktion habe um auf einer Webseite die im Flash des yc 
läuft (AVR Net IO) eine Checkbox zu setzen (checked)

Die kann man mit Sicherheit auch auf ein Array erweitern, würde dann 
aber wieder ein Rattenschwanz hinter sich ziehen... und so fit bin ich 
da drin auch nicht, was die porgrammierung angeht...
1
  //---------------------------------------------------------------
2
      // Einsetzen des Port Status %PORTxy durch "checked" wenn Portx.Piny = 1
3
      // x: A..G  y: 0..7 
4
      //---------------------------------------------------------------
5
6
      if (strncasecmp_P("PORT",http_entry[index].new_page_pointer,4)==0)
7
      {
8
        unsigned char pin  = (pgm_read_byte(http_entry[index].new_page_pointer+5)-48);  
9
        b = 0;
10
        switch(pgm_read_byte(http_entry[index].new_page_pointer+4))
11
        {
12
        
13
          case 'A':            
14
            b = (StatusPort1  & (1<<pin));
15
            //usart_write_str0("-Port1-");
16
            break;
17
            
18
          case 'B':
19
             b = (StatusPort2 & (1<<pin));
20
            //usart_write_str0("-Port2-");
21
            break;

von Flohzirkus (Gast)


Lesenswert?

Probier' einfach

1
        if      (i< 8)  StatusPort1 |= ( 1 << i );
2
        else if      (i< 16) StatusPort2 |= ( 1 << (i-8) );
3
        else if      (i< 24) StatusPort3 |= ( 1 << (i-16) );
4
        else if      (i< 32) StatusPort4 |= ( 1 << (i-24) );      
5
        else if      (i< 40) StatusPort5 |= ( 1 << (i-32) );

Aber das Umschreiben in ein Array wäre sicherlich zu empfehlen.

Gruß

von Markus P. (sebastianwurst)


Lesenswert?

Habs jetzt so gelöst:
else if      (i< <y>) StatusPorty<x> |= ( 1 << (i%8) );

Also:
1
 if (ausgaenge_status[i]) 
2
      {
3
        if      (i< 8)  StatusPort1 |= ( 1 << (i%8) );
4
        else if      (i< 16) StatusPort2 |= ( 1 << (i%8) );
5
        else if      (i< 24) StatusPort3 |= ( 1 << (i%8) );
6
        else if      (i< 32) StatusPort4 |= ( 1 << (i%8) );      
7
        else if      (i< 40) StatusPort5 |= ( 1 << (i%8) );  
8
        else if      (i< 48) StatusPort6 |= ( 1 << (i%8) );  ......

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.