Forum: Mikrocontroller und Digitale Elektronik C + TFT +SD ==> Unlogischer Fehler. Mit Wissenschaftlichen Mitteln nicht erklärbar!


von M. Н. (Gast)


Lesenswert?

Hallo Leute,

ich habe ein Display mit SSD1963 Controller an einem PIC32MX340F512H.

ICh versuche ein Bild von SD-Karte (Roh-Format) an das Display zu 
senden.

Der Code:
1
for(i=0;i<(800*480);i++)
2
{
3
  f_read(&file1, buffer, 2, &read);
4
  LCD_WR_Data((((short)buffer[1])<<8)+buffer[0]);
5
}
Die Funktion f_read liest die daten korrekt ein... (bereits überprüft).
Leider Stürtzt der µC nach etwa der Hälfte des Bildes ab und bricht die 
for Schleife ab.. und setzt alle Pins auf 0.
Mit folgendem Code passiert das nicht:
1
for(i=0;i<(800*480);i++)
2
{
3
  f_read(&file1, buffer, 2, &read);
4
        buffer[0] = 0xFF;
5
        buffer[1] = 0x1C;
6
  LCD_WR_Data((((short)buffer[1])<<8)+buffer[0]);
7
}
Die Daten werden bei diesem Code ausgelesen und durch Konstanten 
überschrieben. Dann stürtzt der Controller nicht ab und füllt das ganze 
Bild mit 0x1CFF-Pixeln (RGB565 16-bit Color).

Ich finde es sehr komisch, dass der Controller Schei*e baut, wenn die 
Daten im ursprünglichen Zustand bleiben.


Kann mir jemand helfen..

Gruß M.H.

Ps Ich weiß, dass der Fehler technisch eigentlich gar nicht möglich sein 
dürfte.. meine einzige Hoffnung ist, dass der C32 Compiler da was kaputt 
compiliert bzw. optimiert.


Bitte helft mir...

von Floh (Gast)


Lesenswert?

Buffer ist wie definiert? Möglicherweise zu groß für deinen RAM?

von M. Н. (Gast)


Lesenswert?

Floh schrieb:
> Buffer ist wie definiert? Möglicherweise zu groß für deinen RAM?

char buffer[32];


Ram : 1756 Bytes von 32768 Bytes... Also noch mehr als genug verfügbar

von Martin M. (capiman)


Lesenswert?

Kommentiere mal die Zeile

LCD_WR_Data((((short)buffer[1])<<8)+buffer[0]);

aus und teste, ob die Schleife dann komplett durchläuft.

Was macht LCD_WR_Data?

von M. Н. (Gast)


Lesenswert?

Disassembly sieht so aus:
1
223:                   f_read(&file1, buffer, 2, &read);
2
9D00A800  27C30090   addiu       v1,s8,144
3
9D00A804  27C200B0   addiu       v0,s8,176
4
9D00A808  3C04A000   lui         a0,0xa000
5
9D00A80C  248404B4   addiu       a0,a0,1204
6
9D00A810  00602821   addu        a1,v1,zero
7
9D00A814  24060002   addiu       a2,zero,2
8
9D00A818  00403821   addu        a3,v0,zero
9
9D00A81C  0F400DE8   jal         0x9d0037a0
10
9D00A820  00000000   nop         
11
224:                   LCD_WR_Data((((short)buffer[1])<<8)+buffer[0]);
12
9D00A824  83C20091   lb          v0,145(s8)
13
9D00A828  3042FFFF   andi        v0,v0,0xffff
14
9D00A82C  00021200   sll         v0,v0,0x8
15
9D00A830  3043FFFF   andi        v1,v0,0xffff
16
9D00A834  83C20090   lb          v0,144(s8)
17
9D00A838  3042FFFF   andi        v0,v0,0xffff
18
9D00A83C  00621021   addu        v0,v1,v0
19
9D00A840  3042FFFF   andi        v0,v0,0xffff
20
9D00A844  7C021620   seh         v0,v0
21
9D00A848  00402021   addu        a0,v0,zero
22
9D00A84C  0F402C85   jal         0x9d00b214
23
9D00A850  00000000   nop

von M. Н. (Gast)


Lesenswert?

Martin Maurer schrieb:
> Kommentiere mal die Zeile
>
> LCD_WR_Data((((short)buffer[1])<<8)+buffer[0]);
>
> aus und teste, ob die Schleife dann komplett durchläuft.

Ja die Schleife läuft dann komplett durch.

Martin Maurer schrieb:
> as macht LCD_WR_Data?
1
void LCD_WR_Data(short dat)
2
{
3
  PORTESET = (1<<5) | (1<<1);
4
  PORTB = dat;
5
  PORTECLR = (1<<3);
6
7
        /*Hier sind in echt ein paar asm("nop"); Befehle dazwischen. Hab    die jetzt halt eingespart, damit man das besser lesen kann*/
8
9
  PORTESET = (1<<3);
10
  
11
}

von M. Н. (Gast)


Lesenswert?

ich hatte auch das Problem, dass er bei:

#define LCD_RS PORTDbits.RD1


LCD_RS = 0;

den ganzen PortD auf 0 gesetzt hat.

Wenn ich dann geschrieben habe

PORTDbits.RD1 = 0;

dann ist nur das Bit 1 auf 0 gegangen...

Also auch so ein komischer Compiler-Schrott.

von M. Н. (Gast)


Lesenswert?

Ich geh jetzt bloß ins Bett...


Hab seit gestern 20 Uhr dran gesessen. Sollte mal schlafen...

von Johannes E. (cpt_nemo)


Lesenswert?

M. H. schrieb:
> Leider Stürtzt der µC nach etwa der Hälfte des Bildes ab und bricht die
> for Schleife ab.. und setzt alle Pins auf 0.

Was genau meinst du mit "bricht die for Schleife ab"? Macht der 
Controller einen Reset oder geht die Ausführung nach der for-Schleife 
weiter?

Hast du statt:
1
buffer[0] = 0xFF;
2
buffer[1] = 0x1C;

auch mal andere Werte ausprobiert (z.B. zwei mal 0x00 oder zwei mal 
0xFF)? Wenn einer dieser beiden Werte auch zum Absturz führt, dann liegt 
es vielleicht an einer einzelnen Leitung, die einen Kurzschluss zu GND 
oder VCC hat.

M. H. schrieb:
> Ich finde es sehr komisch, dass der Controller Schei*e baut, wenn die
> Daten im ursprünglichen Zustand bleiben.

Ich würde erst mal nicht davon ausgehen, dass der Compiler daran schuld 
ist; vermutlich eher ein Hardware-Problem. Kannst du den Code auch im 
Simulator ausführen?

von Frank K. (fchk)


Lesenswert?

Welchen Compiler nimmst Du?

Meine Empfehlung: C32 Version 1.12 (die letzte 1'er) und MPLAB8. Genau 
diese Kombination!

Probiere es damit mal.

fchk

von M. Н. (Gast)


Lesenswert?

Frank K. schrieb:
> Welchen Compiler nimmst Du?
Ich weiß nicht genau, aber in MPLAB, ich benutze übrigens 8.85, zeigt er 
mir bei Language Toolsuite immer v2.02 bei allen Exe-Dateien des 
Compilers.
Also denke ich dass ich compiler v2.02 habe.

von M. Н. (Gast)


Lesenswert?

Frank K. schrieb:
> Meine Empfehlung: C32 Version 1.12 (die letzte 1'er)

Wo bekomme ich die her? Bei Microchip gibt's nur die Neueste: v2.02a.

von M. Н. (Gast)


Lesenswert?

Johannes E. schrieb:
> Hast du statt:
> buffer[0] = 0xFF;
> buffer[1] = 0x1C;
>
> auch mal andere Werte ausprobiert (z.B. zwei mal 0x00 oder zwei mal
> 0xFF)?

Ja habe ich. Das funktioniert mit jedem Wert.

Johannes E. schrieb:
> Was genau meinst du mit "bricht die for Schleife ab"? Macht der
> Controller einen Reset oder geht die Ausführung nach der for-Schleife
> weiter?

Ja, er macht einfach nach der for-Schleife weiter und beginnt mit einem 
VS1053b eine MP3-Datei wiederzugeben. Das funktioniert super.

Edit:

Interessant ist auch:
Wenn ich schreibe
1
for(i=0;i<(800*480);i++)
2
{
3
  LCD_WR_Data(i);
4
}
Dann zeigt er auf'm Display das Muster an, das dadurch entsteht. 
Funktioniert.

Wenn ich aber schreibe:
1
for(i=0;i<(800*480);i++)
2
{
3
  LCD_WR_Data(~i);
4
}
gehen sofort alle Pins des µC auf 0. und dann wieder in den 
ursprünglichen zustand. (Dauert keine Millisekunde). Dannach macht der 
Controller dann einfach weiter (nach der for schleife mit dem Rest des 
Programms). Dadurch wird dann das Display geresettet.

von Martin M. (capiman)


Lesenswert?

Wie hast Du eigentlich i angelegt?
Hast Du (als Workaround) schon mal versucht
statt for-next ein while zu benutzen?
Oder 2 kleinere Schleifen?

Hast Du mal geschaut, ob irgendwo beschrieben ist,
was in der v2.02a verändert wurde?
Vielleicht mal updaten auf die v2.02a?

Falls das Projekt übertragbar wäre:
Könntest Du das gesamte Projekt mal hochladen?
Vielleicht könnte Frank es zum Test mit seiner Version übersetzen?

von M. Н. (Gast)


Lesenswert?

Martin Maurer schrieb:
> Wie hast Du eigentlich i angelegt?

int i;

Ich werde mal schauen, was bei der neuen Version anders ist.

von M. Н. (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab jetzt mal die Installer exe von C32 im Downloads Ordner 
wiedergefunden. Es ist die v2.02a.


Hab jetzt mal das Projekt angehängt. Ist aber ziemlich verwirrend, da es 
nur zum testen gadacht war. Sieht halt 'n bisschen durcheinander aus...

von Arc N. (arc)


Lesenswert?

Wie wird denn gedebuggt?
Auf dem Port B liegen normalerweise auch PGEC1, PGED1...
DEVCFG0 passend gesetzt?

von Der (Gast)


Lesenswert?

Tipp:

Schreibe mal bei den benötigten Variablen das Vorzeichen hin. Am Besten 
unsigned.

Dann kannst du folgenden Code verwenden und mit SingeStep debuggen, am 
besten im Dissasembly (Optimierung ausschalten). So siehst du genau, an 
welcher Stelle er aussteigt.
1
...
2
unsigned short BufferTemp;
3
...
4
5
for(i=0;i<(800*480);i++)
6
{
7
   f_read(&file1, buffer, 2, &read);
8
   buffer[0] = 0xFF;
9
   buffer[1] = 0x1C;
10
   BufferTemp = (unsigned short)(buffer[1])<<8);
11
   BufferTemp = BufferTemp + (unsigned short)buffer[0];
12
   LCD_WR_Data(BufferTemp);
13
}

von M. Н. (Gast)


Lesenswert?

Geht. Wenn ich aber das
1
buffer[0] = 0xFF;
2
buffer[1] = 0x1C;
weglasse

verreckt alles wieder

von Frank K. (fchk)


Lesenswert?

M. H. schrieb:
> Frank K. schrieb:
>> Meine Empfehlung: C32 Version 1.12 (die letzte 1'er)
>
> Wo bekomme ich die her? Bei Microchip gibt's nur die Neueste: v2.02a.

Das ist die Archiv-Seite. Da gibts jede alte Version.

http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en023073

fchk

von Der (Gast)


Lesenswert?

Steht denn in BufferTemp der richtige Wert?

Wo gibt es Doku zu f_read? Riecht ein bisschen nach Stack Overflow.

Gruß

von Der (Gast)


Lesenswert?

Nachtrag:

In der Variable read steht, wie viele Bytes tatsächlich gelesen wurden. 
Ist read groß genug?
Überprüfe auch nach jedem f_read, ob tatsächlich genügend Bytes gelesen 
wurden.

von M. Н. (Gast)


Lesenswert?

wenn ich die gelesenen Bytes über f_write(&file2 ....

in eine zweite Datei schreibe, dann hat er die Datei 1 zu 1 kopiert. 
Habs nachgeprüft. Die Daten werden 100% korrekt ausgelesen.

M. H. schrieb:
> Interessant ist auch:
> Wenn ich schreibefor(i=0;i<(800*480);i++)
> {
>   LCD_WR_Data(i);
> }
> Dann zeigt er auf'm Display das Muster an, das dadurch entsteht.
> Funktioniert.
>
> Wenn ich aber schreibe:for(i=0;i<(800*480);i++)
> {
>   LCD_WR_Data(~i);
> }
> gehen sofort alle Pins des µC auf 0. und dann wieder in den
> ursprünglichen zustand. (Dauert keine Millisekunde). Dannach macht der
> Controller dann einfach weiter

Hier hat das gar nichts mit SD-Karte zu tun. Es funktioniert nicht nur 
weil ich ~i statt i verwende.

Ich verzweifle an dem Problem. Vor Allem, dass das so unlogisch ist 
raubt einem den letzten Nerv

von Karlheinz (Gast)


Lesenswert?

Hallo,

> for(i=0;i<(800*480);i++)

wie ist denn dein "i" definiert ???, hoffentlich ein "long" denn sonst 
wird er nie fertig, weil
800*480 = 38400 (0x5dc00)

von Karlheinz (Gast)


Lesenswert?

Hallo nochmal
Korrektur, da eine Null vergessen in 384000

> for(i=0;i<(800*480);i++)

 wie ist denn dein "i" definiert ???, hoffentlich ein "long" denn sonst
 wird er nie fertig, weil
 800*480 = 384000 (0x5dc00)

von Glaskugel (Gast)


Lesenswert?

Geht es mit :

buffer[0] = 0x00;
buffer[1] = 0x00;

Wenn nicht, sollte klar sein woran es liegt

von Marco L. (lehmi)


Lesenswert?

Hast du mal die Datenleitungen auf Kurzschlüsse untereinander und zu 
Masse / Versorgung geprüft? Irgendein Bitmuster scheint den Controller 
zu resetten oder die Spannungen zusammenbrechen zu lassen.

Grüße

von M. Н. (Gast)


Lesenswert?

Ich habe etwas festgestellt.

Wenn ich schreibe PORTE |= (1<<4); ,

dann werden sporadisch andere Bits des Ports auf null gesetzt. Das 
dürfte doch eigentlich nicht passieren, oder?

Werde die Hardware nochmal checken.

Martin Maurer (capiman) hat mir freundlicherweise 2 Hex-Files mit seinen 
Versionen compiliert.
Das Problem besteht aber weiterhin...

von Marvin M. (Gast)


Lesenswert?

Hallo,

hast du noch irgendeine Interrupt-Routine am Laufen? Evtl. zerhackts dir 
da irgendwelche nicht-atomaren Zugriffe?

von M. Н. (Gast)


Lesenswert?

Es läuft nur ein Coretimer Interrupt.Der zählt ein paar Variablen hoch 
und generiert jede Millisekunde die Zeit für Das FAT-Modul. Habs schon 
probiert ohne. Klappt trotzdem nicht

von Jan G. (jan80)


Lesenswert?

Die Stromversorgung von MC ist aber ok? Kondensator vorhanden? Mal einen 
anderen MC getestet? Die können durchaus auch mal defekt sein...

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.