Forum: Mikrocontroller und Digitale Elektronik Ratlosigkeit obwohl nur ein Bit getestet wird


von Michael D. (etzen_michi)


Angehängte Dateien:

Lesenswert?

Irgendwie komme ich nichtmehr weiter ...
Es geht um ein Unterprogramm, welches einen Wert übergeben bekommt und 
die Bits 11 - 0 ausließt, je nachdem ob 0 oder 1 einen PortPin setzt und 
dann einmal SCLK toogled.


Wenn ich
1
PORTD|= 1<<SIN;
2
for(int i=0; i<=11; i++) {
3
   tSCLK();
4
}
mache geht alles.

Wenn ich
1
//PORTD|= 1<<SIN;
2
int i;
3
for(i=0; i<=11; i++) {
4
   if((GS&0x800)) {
5
      PORTD|= 1<<SIN;
6
   } else {
7
      //PORTD&= ~(1<<SIN);
8
      PORTD|= 1<<SIN;
9
   }
10
   tSCLK();
11
   GS<= 1;
12
   //GS*= 2;
13
}
sollte eig. nichts anderes passieren können, aber ich bekomme nur Mist 
raus (der SIN wird zeitweise auf 0 geschaltet.

Aus dem erstellten Code werde ich auch nicht ganz schlau weil da 
irgendwie ganze Teile fehlen.
Das Programm läuft weder mit wie auch ohne Optimierung.
1
0000012c <GSData>:
2
3
void GSData(volatile int GS) {
4
 12c:  df 93         push  r29
5
 12e:  cf 93         push  r28
6
 130:  00 d0         rcall  .+0        ; 0x132 <GSData+0x6>
7
 132:  cd b7         in  r28, 0x3d  ; 61
8
 134:  de b7         in  r29, 0x3e  ; 62
9
 136:  9a 83         std  Y+2, r25  ; 0x02
10
 138:  89 83         std  Y+1, r24  ; 0x01
11
 13a:  20 e0         ldi  r18, 0x00  ; 0
12
 13c:  30 e0         ldi  r19, 0x00  ; 0
13
          }
14
     }
15
     */
16
     int i;
17
     for(i=0; i<=11; i++) {
18
          if((GS&0x800)) {
19
 13e:  89 81         ldd  r24, Y+1  ; 0x01
20
 140:  9a 81         ldd  r25, Y+2  ; 0x02
21
 142:  93 ff         sbrs  r25, 3
22
 144:  02 c0         rjmp  .+4        ; 0x14a <GSData+0x1e>
23
               PORTD|= 1<<SIN;
24
 146:  91 9a         sbi  0x12, 1  ; 18
25
 148:  01 c0         rjmp  .+2        ; 0x14c <GSData+0x20>
26
          } else {
27
               PORTD&= ~(1<<SIN);
28
 14a:  91 98         cbi  0x12, 1  ; 18
29
     }
30
     tXLAT();
31
}


Vielleicht sieht hier ja irgendwer direkt irgendeinen groben Fehler... 
Google habe ich bemüht und die Forensuche auch.

*Info: Bei GS<= 1; meldet er das der berechnete Wert nicht verwendet 
wird, obwohl er doch beim nächsten Schleifendurchlauf wieder verglichen 
werden sollte.
volatile bringt keine besserungen.
Desweiteren verstehe ich auch nicht wie er auf die Idee kommt obwohl 
nirgends im Code steht er solle den Pin auf Low setzen dieser auf Low 
gesetzt wird.

Die Info das der Teil nicht funktioniert habe ich nicht nachgemessen, 
sehe ich auf der angeschlossenen Hardware da nicht alle LED`s 
gleichmäßig aufleuchten, sondern teilweise gedimmt sind (Wert < 4095).

von Noname (Gast)


Lesenswert?

>Bei GS<= 1; meldet er das der berechnete Wert nicht verwendet
>wird, obwohl er doch beim nächsten Schleifendurchlauf wieder verglichen
>werden sollte.

Kein Wunder. Was soll  GS<= 1; - ein Vergleich ohne Entscheidung oder 
Zuweisung - auch bewirken?

Das
   GS<= 1;

ist nicht das selbe wie das

   //GS*= 2;


Kann es sein, das es

GS <<= 1

heissen sollte?

von Stefan E. (sternst)


Lesenswert?

Michael D. schrieb:
> Vielleicht sieht hier ja irgendwer direkt irgendeinen groben Fehler...
1
GS<= 1;
->
1
GS <<= 1;

von Michael D. (etzen_michi)


Lesenswert?

Mit
1
GS<<= 1;
das gleiche Problem
1
0000012c <GSData>:
2
3
void GSData(volatile int GS) {
4
 12c:  df 93         push  r29
5
 12e:  cf 93         push  r28
6
 130:  00 d0         rcall  .+0        ; 0x132 <GSData+0x6>
7
 132:  cd b7         in  r28, 0x3d  ; 61
8
 134:  de b7         in  r29, 0x3e  ; 62
9
 136:  9a 83         std  Y+2, r25  ; 0x02
10
 138:  89 83         std  Y+1, r24  ; 0x01
11
          for(j=0; j<=11; j++) {
12
               tSCLK();
13
          }
14
     }
15
     */
16
     PORTD|= 1<<SIN;
17
 13a:  91 9a         sbi  0x12, 1  ; 18
18
 13c:  20 e0         ldi  r18, 0x00  ; 0
19
 13e:  30 e0         ldi  r19, 0x00  ; 0
20
     int i;
21
     for(i=0; i<=11; i++) {
22
          if((GS&0x800)) {
23
 140:  89 81         ldd  r24, Y+1  ; 0x01
24
 142:  9a 81         ldd  r25, Y+2  ; 0x02
25
               PORTD|= 1<<SIN;
26
          } else {
27
               //PORTD&= ~(1<<SIN);
28
               PORTD|= 1<<SIN;
29
 144:  91 9a         sbi  0x12, 1  ; 18
30
     }
31
     tXLAT();
32
}

Die ganzen *Alternativen, Extras welche als Kommentar vorhanden sind 
habe ich bereits alle schon ausgetestet ..

Aber zumindest eine Frage ist nun beantwortet, bleibt noch: Warum setzt 
der den Pin Low?

von Noname (Gast)


Lesenswert?

Hm. Es scheint mir das der Code genau das macht, was Du schreibst.

Du rufst doch GSData mit einem konstanten Argument auf. Da kann sich der 
Compiler an fünf Fingern abzählen, welches Bit er setzt soll. Und die 
Anzahl der Schleifendurchläufe ändert daran auch nichts.

von Michael D. (etzen_michi)


Lesenswert?

Ha ... Fehler gefunden ...

Seid zwei Tagen am Suchen und rumwursteln, nun gehts.

In der .c steht nicht:
1
for(i=0; i<=11; i++)..
sondern
1
for(i=0; i<= 47; i++) {
2
   for(j=0; j<= 11; j++) ...

Habe das "for48" anfangs drinne gehabt um die zusammensetzung des Codes 
zu testen, dann aber vergessen raus zu nehmen.

Problem war also das er nach jeder LED (12Bit) tXLAT(); ausgeführt hat, 
was dazu geführt hat das die TLC die Daten im Schieberegister 
durcheinander gewürfelt haben.

Habe nun das überflüssige tXLAT(); herausgenommen und es läuft.

Frage mich warum man die Lösung erst findet wenn man sich öffentlich 
blamiert hat.


Nochmals vielen Dank.

von R. F. (rfr)


Lesenswert?

Michael D. schrieb:
> Frage mich warum man die Lösung erst findet wenn man sich öffentlich
>
> blamiert hat.

Wegen des gesteigerten Lerneffektes.


:-))


Gruss

Robert

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.