Forum: Mikrocontroller und Digitale Elektronik Bit in Byte mit Schleife schieben.


von Alex (Gast)


Lesenswert?

Hi,

ich habe mehrere Eingangsplatinen die ich mit jeweils zwei 
Schieberegister bestückt habe. Ich schiebe mit folgender Schleife meine 
1en und 0en in das "Eingang[i]" Array.
Für eine andere Auswertung benötige ich jedoch die Bits im Byte, hierfür 
habe ich ein ByteArray angelegt "StatusEingangKarte[j]" -> uint16_t 
StatusEingangKarte[EPL_Anzahl];
In diesem ByteArray sollen jetzt von der ersten Karte die 16 bit 
reingeschoben werden, wie mache ich das am besten?
Ich habe es so versucht, nur wie bekomme ich den nächsten "j" oder "k" 
hin der mir eine neue Karte signalisiert?!?! Alle 16 muss "j" und "k" 
erhöht werden?!?!

Habt ihr da eine Idee?
1
 
2
3
4
  int i = 0; 
5
      //Abfragen welches Registerbit gesetzt -> mit clock weiter schiebenEPL_Anzahl
6
    for(i=(EPL_Anzahl * 16)-1;i>=0;i--)
7
    {
8
          
9
      if (PINA & (1<<PINA0)) 
10
      { // Logisch 0 wenn Schalter nicht gedrückt da Pullup an
11
      Eingang[i] = 0;     
12
      
13
      
14
        int j = 0;
15
        
16
        for(j=EPL_Anzahl ; j>=0; j--)
17
          {
18
          StatusEingangKarte[j] &= ~(1 << i);
19
          }
20
      
21
      
22
23
      }
24
      else 
25
      {
26
      Eingang[i] = 1;  
27
      
28
      
29
        int k = 0;
30
        
31
        for(k=EPL_Anzahl; k>=0; k--)
32
          {
33
          StatusEingangKarte[k] |= ( 1 << i );
34
          }
35
  
36
      }

von Hmm (Gast)


Lesenswert?

Ich möchte mir den Rat erlauben, die Frage noch einmal, wesentlich 
detaillierter und durchdachter zu formulieren, einen Schaltplan 
anzuhängen und den Code zu dokumentieren. Vor allem auch genau zu 
beschreiben, was das Ergebnis sein soll.
Es mag sein, das ich die Ausnahme bin, aber ich verstehe nämlich nur, 
das Du Bits einlesen willst und prüfen welches gesetzt ist. An sich ist 
das trivial, auch wenn ich akzeptiere das Du vielleicht an dieser Stelle 
Schwierigkeiten hast. Wo aber da j und k in's Spiel kommen und warum das 
eigentlich genau in Deinem Fall schwierig ist kann ich nicht erkennen.

von Alex (Gast)


Lesenswert?

OK, unten habe ich den Code auch kommentiert. Hoffe das hilft und ihr 
könnt mir helfen.

Ich denke , dass ich irgendwie mit Modul arbeiten muss, das "j" von:
1
        for(j=EPL_Anzahl ; j>=0; j--)
2
          {
3
          StatusEingangKarte[j] &= ~(1 << i);
4
          }

muss meiner Meinung nach alle 16 mal "i"erhöht werden, also
i= 16
i= 32
i= 48

1
void Eingaenge_abfragen ()
2
{
3
4
    PORTC |= (1<<PC4);
5
6
    // Mit PL alle Eingänge in das Register schieben.
7
8
    // PL auf High
9
    PORTC |= (1<<PC5);
10
    // PL auf Low
11
    PORTC &= ~(1<<PC5);
12
    // PL auf High
13
    PORTC |= (1<<PC5);
14
15
    int i = 0; 
16
      //Abfragen welches Registerbit gesetzt -> mit clock weiter schiebenEPL_Anzahl
17
    for(i=(EPL_Anzahl * 16)-1;i>=0;i--)
18
    {
19
          
20
      if (PINA & (1<<PINA0)) 
21
      { // Logisch 0 wenn Schalter nicht gedrückt da Pullup an
22
        // Eingang[0-144] ist das Array, da stehen pro "i" nur 1 oder 0 drin.
23
        //           144 da 9 Eingangskarten
24
      Eingang[i] = 0;     
25
      
26
           // jetzt brauche ein Byte z.B: StatusEingangKarte[0] das z.B so aussieht "0101010101010011" insgesamt 16 Bits 
27
         //  da meine Eingangskarte 2x8 Schieberegister hat
28
        int j = 0;      
29
      
30
        for(j=EPL_Anzahl ; j>=0; j--)
31
          {
32
          StatusEingangKarte[j] &= ~(1 << i);
33
          }
34
      }
35
      else 
36
      {
37
      Eingang[i] = 1;  
38
      
39
      
40
        int k = 0;
41
        
42
        for(k=EPL_Anzahl; k>=0; k--)
43
          {
44
          StatusEingangKarte[k] |= ( 1 << i );
45
          }
46
      }        
47
                    
48
      // Mit Clock weiterschieben
49
50
      // Clock auf High
51
      PORTC |= (1<<PC4);
52
      // Clock auf Low
53
      PORTC &= ~(1<<PC4);
54
      // Clock auf High
55
      PORTC |= (1<<PC4);    
56
    }  // For Ende    
57
}

von Hmm (Gast)


Lesenswert?

Na gut. War ja nur ein Rat. Musst Du ja nicht befolgen.Vielleicht kann 
ja ein anderer was mit Deiner Frage anfangen. Viel Glück.

Und bevor Du jetzt antwortest: "Aber ich habe doch..."
nochmal dies:
>die Frage noch einmal, wesentlich
detaillierter und durchdachter zu formulieren, einen Schaltplan
anzuhängen [...]. Vor allem auch genau zu
beschreiben, was das Ergebnis sein soll.

von MWS (Gast)


Lesenswert?

Vom Grundkonzept wär's besser, wenn für 144 Bits nicht 144 Bytes in 
Eingang[] verwendet werden, sondern eben nur tatsächlich 144 Bits in 18 
Bytes. Dann liegt die Daten doch bereits in der gewünschten Form vor.

von Ralf G. (ralg)


Lesenswert?

Ich versuche mal zu verstehen, was du willst:
- Daten von Schieberegister einlesen und in uint16_t-Variable speichern.
- nächstes Schieberegister auswählen
- das ganze von vorn

Da würde ich erstmal, wegen der Übersichtlichkeit, den Empfang in eine 
eigene Funktion auslagern:
1
// 'Pseudocode'
2
uint16_t Empfang()
3
// Es scheint mir so, als ob die Bits von allen Schieberegistern
4
// nacheinander über den selben Pin eingelesen werden (?)
5
// Ansonsten der Routine noch den Port und die Pinnummer der Daten
6
// (+evtl Clock) übergeben
7
{
8
    uint16_t b = 0;
9
10
    for (uint8_t i = 0; i < 16; i++)
11
    {
12
- hier Takt ausgeben
13
14
        b = b << 1;
15
        if (PORT_DATA & (1 << PIN_DATA))
16
        {
17
            b |= 1;
18
        }
19
    }
20
    return b;
21
};

Das Ergebnis kommt in das entsprechende 16-Bit-Element des Arrays mit (n 
* Platinen) Einträgen.

von Alex (Gast)


Lesenswert?

Ja in etwa war das schon richtig was du meintest, die eigene Routine 
habe ich ja schon.(void Eingaenge_abfragen ())
So sieht die Routine aus die die Eingänge abfragt und den Status des 
Bits ein "Eingang[xx]" einträgt (s.unten)
Drück ich am 20ten Eingang den Taster wird Eingang[20] TRUE.
Das soll auch so bleiben, jetzt will ich es nur noch haben, dass in  16 
Bits großen Bytes "StatusEingangKarte[xx]" in diesem Fall das 
StatusEingangKarte[1] so aussieht: "0000 0000 0000 1000"
1
void Eingaenge_abfragen ()
2
{
3
4
    PORTC |= (1<<PC4);
5
6
    // Mit PL alle Eingänge in das Register schieben.
7
8
    // PL auf High
9
    PORTC |= (1<<PC5);
10
    // PL auf Low
11
    PORTC &= ~(1<<PC5);
12
    // PL auf High
13
    PORTC |= (1<<PC5);
14
15
    int i = 0; 
16
      //Abfragen welches Registerbit gesetzt -> mit clock weiter schiebenEPL_Anzahl
17
    for(i=(EPL_Anzahl * 16)-1;i>=0;i--)
18
    {
19
          
20
      if (PINA & (1<<PINA0)) 
21
      {
22
      Eingang[i] = 0;     
23
      }
24
      else 
25
      {
26
      Eingang[i] = 1;  
27
      }     
28
                    
29
      // Mit Clock weiterschieben
30
31
      // Clock auf High
32
      PORTC |= (1<<PC4);
33
      // Clock auf Low
34
      PORTC &= ~(1<<PC4);
35
      // Clock auf High
36
      PORTC |= (1<<PC4);    
37
    }  // For Ende    
38
}

von Marcus (Gast)


Lesenswert?

Kannst Du die Schieberegister mit SPI auslesen? Mit dem 74HC165 geht das 
z.B. prima. Dann kannst Du direkt mit ganzen Bytes hantieren  und es 
wird viel einfacher und übersichtlicher?

von Falk B. (falk)


Lesenswert?

@ Alex (Gast)

>So sieht die Routine aus die die Eingänge abfragt und den Status des
>Bits ein "Eingang[xx]" einträgt (s.unten)

Hmmm.

>Drück ich am 20ten Eingang den Taster wird Eingang[20] TRUE.

Specherverschwendung.

>Das soll auch so bleiben, jetzt will ich es nur noch haben, dass in  16
>Bits großen Bytes

Ein Byte hat immer 8 Bit, nicht mehr nicht weniger. Ein Wort ist nicht 
streng definiert, oft sind es aber 2 Bytes.

> "StatusEingangKarte[xx]" in diesem Fall das
>StatusEingangKarte[1] so aussieht: "0000 0000 0000 1000"

Mach, was schon mehrere Leute vorgeschlagen haben. Lies die Bits 
systematisch ein und pack sie in ein Byte. Das kann man mehrfach 
wiederholden und hat ein Array. Siehe Bitmanipulation und 
AVR-Tutorial: Schieberegister.

von Thomas E. (thomase)


Lesenswert?

Die Ratestunde ist eröffnet:

Welche Schieberegister? 165, 597, ?
Welcher Controller? SPI, USI
Was wird eingelesen? Wie schnell?
Was soll das Ganze?
Schaltplan?

mfg.

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.