Forum: Mikrocontroller und Digitale Elektronik Array Null Init / Schieberegister


von Murphy S. (student-f)


Lesenswert?

Hallo Jungs und Mädels,

die meisten werden schon beim Thread-Namen die Haare zu Berge stehen.

Ich blicke aber gerade nicht "durch"..

Folgendes Helferlein-µC:

OK: Schieberegister 1 x 8 Bit = 1 Schieberegister
OK: Schieberegister 2 x 8 Bit = 2 Schieberegister
NIcht OK: Schieberegister 4 x 8 Bit = 4 Schieberegister Daten-Chaos /

Ich schiebe in einem Schieberegister immer eine Variable mit 32 Stellen 
hinein.(4 x HC9595 etc) Dies geht auch prinzipiell.

Ablauf:
 - Variable für Shiften erzeugen, geht nicht immer "richtig"!
 - Datenbasis: Array 2D ==> mit For schleife erzeuge ich ein long int 
data2 mit 32 Bit stellen. (Aus Array 2D mach eine große Variable)

Die Ausgabe zum Shiftreg erfolgt in einer For-SChleife:

array[a1][b1] = TRUE; // a wird immer an der richtigen Stelle erzeugt. b 
"springt in der Shiftausgabe "hin und her". Eig. Soll in diesem Fall 
erzeugt werden:

0x80,0x00,0x80,0x00 aber es erscheint auch:
0x80,0x00,0x00,0x80
1
a1 = 1;
2
b1 = 1;
3
4
array[a1][b1] = TRUE; //  s.O.
5
6
for(x=0;x<16;x++)          
7
    {
8
    for(y=0;y<16;y++)  
9
      {
10
      if(array[x][y] == TRUE)    // Stelle als True/ON markiert?
11
        {
12
        data2 |= (1L << (31-y)) | (1L << (x));   
13
        sent_Byte_SHIFT_MAX(data2);  // Bit an Stelle  x senden
14
        data2 = 0;          // Damit nichts "vorheriges" geshiftet wird
15
        }
16
      else
17
        {
18
        sent_Byte_SHIFT_MAX(0); // Wenn keine Daten vorhanden sind, dennoch NUll senden
19
        }
20
      }
21
    }

Daher die Annahme, das das Array keine entsprechenden Daten enthält, so 
beim starten alles auf Null Init:
1
   for (i= 0;i<16;i++)
2
    {
3
    for (j= 0;j<16;j++)
4
      {
5
      array[i][j] = OFF;
6
      }
7
    }
8
// OFF == 0;
 ==> Mit dem Null Init steht der µC und es wird rein gar nix gesendet


Es kann doch nicht so schwer sein...

Danke!

von Peter II (Gast)


Lesenswert?

Murphy Spider schrieb:
> data2 |= (1L << (31-y)) | (1L << (x));
>         sent_Byte_SHIFT_MAX(data2);  // Bit an Stelle  x senden

wie gross ist denn data2? Wenn du 31bit nach links schiebst wird es wohl 
kein byte sein. Aber dann machst du sent_byte - macht das sinn?

von Murphy S. (student-f)


Lesenswert?

Peter II schrieb:
> Murphy Spider schrieb:
>> data2 |= (1L << (31-y)) | (1L << (x));
>>         sent_Byte_SHIFT_MAX(data2);  // Bit an Stelle  x senden
>
> wie gross ist denn data2? Wenn du 31bit nach links schiebst wird es wohl
> kein byte sein. Aber dann machst du sent_byte - macht das sinn?

Hi,

data2 ist wie folgt definiert mit:
1
  long int data2=0; //==> entspricht 32 Bit Stellen

Oder irre ich mich?

Achso:

x&y können max 0-15 dezimal betragen

von Peter II (Gast)


Lesenswert?

Murphy Spider schrieb:
> data2 ist wie folgt definiert mit:  long int data2=0; //==> entspricht 32 Bit 
Stellen
> Oder irre ich mich?

nein das sollte schon stimmen, aber dann macht ja wohl

send_byte keinen sinn - wie gross ist denn dort der Parameterm, vom 
namen her würde ich byte erwarten.

von Murphy S. (student-f)


Lesenswert?

Hmm, der Name macht wahrlich keinen Sinn, hast Recht :-)
1
void sent_Byte_SHIFT_MAX(long int data)
2
{ 
3
  uint8_t i;
4
      for(i = 32; i; i-- )      // 32 Bit shiften 
5
      {
6
       //Daten ausgeben Anfang
7
         PORTB &= ~(1<<MOSI);     
8
   
9
      if(data & 0x80000000 )         //MSB first
10
       {
11
          PORTB |= (1<<MOSI);     
12
        }
13
      // Daten ausgeben Ende
14
15
  //SCLK ausgeben
16
      PORTB |= (1<<SCK);         
17
    data <<= 1;          
18
      PORTB &= ~(1<<SCK);         
19
      }
20
21
    PORTB |= (1<<SS);             //SS high (RCK)
22
    PORTB &= ~(1<<SS);             //SS low (RCK)
23
}

von Peter II (Gast)


Lesenswert?

ich verstehts auch nicht.

Bist du sicher das du 256(16*16) mal 32bit senden willst? Also sendet du 
bei einem aufruf 8192 bit.

von Murphy S. (student-f)


Lesenswert?

Hi,

ich hatte vor 4 * 8 Bit zu senden und dann den RCK zu setzen...

von Peter II (Gast)


Lesenswert?

du rufst aber

for(x=0;x<16;x++)
    for(y=0;y<16;y++)
        send_byte


damit wird sendbyte 256 mal aufgerufen und sendet jedesmal 32bit.

von Murphy S. (student-f)


Lesenswert?

Japp, das ist schon so von mir gewollt. Ich will bei jedem 256. Aufruf 
die Ausgabe z.B.: array[a1][b1] = TRUE; erzeugen... So ist beim 256. 
Aufruf von sende mir nen Byte zwei Bits gesetzt und 255 mal nix. Das was 
ich nicht verstehe, ist

a) Warum steht der µC, wenn ich das Array zuvor auf "Null" intialisiere
b) Warum ist die 256. Ausgabe nicht immer identisch?

von Huhua (Gast)


Lesenswert?

Welcher µC den?

von Murphy Spider (Gast)


Lesenswert?

Es handelt sich hier um den Attiny45-20PU mit int. RC-Osc@8MHz

von Murphy S. (student-f)


Angehängte Dateien:

Lesenswert?

Hallo,

sollte einer an diesem verregneten Sommertag etwas Zeit haben, so möge 
er sich doch die beigefügten Screenshots anschauen :-)

Zur Problematik neu:

Ich habe 4 Shiftregister, die erst alle Daten erhalten und danach den 
RCK bekommen (damit alle gleichzeitig gesetzt werden!) Allerdings wird 
in meinem Code etwas schief laufen, nur ich blicke gerade nicht durch 
welches. Code s.O. !

array[a1][b1] = TRUE; // a wird immer an der richtigen Stelle erzeugt. b
"springt in der Shiftausgabe "hin und her". Eig. Soll in diesem Fall
erzeugt werden:

x40x0x02x0.PNG  das sollte immer beim 256. mal auftauchen. Leider weiß 
ich nicht, wie ich mit dem Zeroplus zählen kann, ob es z.B. immer bei 
den x-Aufruf der SChleife passiert oder nicht. Das wäre ja nen Debug 
gewesen, den ich nur nicht machen kann, oder weiß wie er zu machen 
wäre..


Viele Grüße

von Karl H. (kbuchegg)


Lesenswert?

Um ehrlich zu sein, hab ich dein Problem nicht wirklich verstanden oder 
im Code ein Problem entdeckt. (Ich hab aber auch nicht sehr intensiv 
gesucht)
Was ich aber entdeckt habe ist, dass du eine der Grundregeln in der 
Programmierung nicht einhältst: Vom Einfach zum Schwierigen.

Das bedeuet: Mach dir eine Funktion, die 8 Bit raustaktet.

Diese Funktion rufst du auf
* aus der ShiftByte Funktion, und hinten nach gibst du einen RCK Puls
* aus der ShiftWord Funktion, in dem du die Funktion 2 mal aufrufst
  einmal für das High-Byte, einmal für das Low-Byte (oder umgekehrt
  je nachdem wie du das brauchst) und hinten nach einen RCK Puls gibts
* aus der ShiftLong Funktion, in dem du sie 4 mal aufrufst, für jedes
  der 4 Bytes des long und hinten nach einen RCK Puls


So würde ich das aufbauen und nicht in jeder der 3 Funktionen das Rad 
für rausshiften immer wieder neu zu erfinden.

Und was du da mit deinem 2D Array aufführst, das ist mir auch nicht 
wirklich klar, ich denke aber es ist das übliche: Angst vor 
Bitoperationen und daher für jedes 'Bit' einen kompletten uint8_t 
verschwenden.

von Murphy S. (student-f)


Lesenswert?

Hallo,

danke für die konstruktive Kritik :-)

Klar, eine 8 Bit Funktion zu verwenden macht Sinn, diese läuft ja 
bereits tadellos und wurde hier nicht erwähnt. Du hast vollkommen Recht, 
das werde ich sofort mal testen, quasi 4mal die Funktion aufrufen und 
danach den RCK setzen.

(macht ja auch Sinn, muss ich zugeben!)

Aus dem 2D-Array sind Koordinaten Werte zu extrahieren ,für das Ziel:

2D-Array [X][Y] wo z.B.  [1][3] den Koordinaten X1 X3 entspricht.

Danke, melde mich...

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.