Hallo Zusammen
Folgendes Problem bekomme ich nicht gelöst:
Ich schreibe per soft SPI Daten an ein Display (DOGXL160x104 pxl, zu 26
pages, pro pixel 2 bit für Graustufen) und parallel dazu lege ich die
Daten in einem Array (lcd_buffer[][]) ab um später pixelweise logische
Verknüpfungen damit machen zu können (Display ist in SPI-mode write
only).
Problembeschreibung:
Nach Aufruf der Produre lcd_clrscr() in lcd.c aus dem Hauptprogramm raus
geht alles gut, aber nachdem durch die for-Schleifen alle array Zellen
beschrieben sind, fängt das Programm neu an und bleibt in einer
Endlosschleife hängen. Manchmal läuft es auch nur bis zur ominösen
150-ten Spalte.
1
voidlcd_clrscr(uint8_tfill)
2
{
3
uint8_ti,j;
4
5
6
for(i=0;i<(XPIXEL-9);i++){
7
printf("i %d",i);
8
lcd_send_command(i&0x0F);//LSB adress
9
lcd_send_command(0x10+(i>>4));//MSB adress
10
11
//set page adress of first half of byte
12
lcd_send_command(0x60);
13
14
for(j=0;j<((YPIXEL/4));j++)
15
{lcd_send_data(fill);
16
lcd_buffer[i][j]=fill;
17
//printf("j %d\n",j);
18
};
19
};
20
21
}
Das für mich unverständliche ist, dass alles normal läuft, wenn ich die
Zeile mit der Zuweisung in das array
1
lcd_buffer[i][j]=fill;
rauslasse.
lcd_buffer[][] wird in lcd.c definiert. Die Sourcen für das Gesamte
Testprojekt im Anhang.
uC: ATMega1284P
Compiler: avr-gcc
riz schrieb:> lcd_send_data(fill);
Ich habe Deine Sourcen kurz überflogen und nirgendwo eine Definition von
"lcd_send_data" gefunden, sondern lediglich folgende Textersetzung in
lcd.h:
1
#define lcd_send_data(data) lcd_send(data, 1)
Diese greift hier natürlich nicht. Ich kann mir nicht vorstellen, dass
sich Dein Projekt ohne Fehler- bzw. Warnmeldungen kompilieren lässt.
Hallo J.u.G.
gehen tut es, warum auch immer. Keine Fehler und das Display tut das was
es soll (wenn ich wie oben beschriebe bei kleinen Spaltenzahlen bleibe).
Hab diese Routine aus dem Forum.
Nichts destotrotz werd' ich das mal ersetzen.
Hab inzwischen neue Info. Wenn ich mehr Funktionalität reinbaue (hab
gerade mal meine TWI-Bibliotheken mit eingebunden), dann geht schon ab
Spalte 50 nix mehr...
Ich vermute es ist irgendein Speicherproblem, aber welches...
riz schrieb:> Das für mich unverständliche ist, dass alles normal läuft, wenn ich die> Zeile mit der Zuweisung in das arraylcd_buffer[i][j]=fill;> rauslasse.
lcd_buffer ist schlappe 4196 Byte groß. Du solltest vielleicht doch mal
im Datenblatt nachschauen, wie groß das SRAM des ATMega168 ist.
Oliver
@Oliver
mir ist schon klar wie groß das array lcd_byte ist, deshalb habe ich ja
auch einen Mega128 genommen. Steht in meinem ersten Beitrag ganz unten.
Kann sein, dass in den Kommentaren in der Source noch irgendwo Mega16
steht, ist aber definitiv ein Mega128, sorry für die Verwirrung.
@Bronco
Watchdog ist nicht an (Fusebit 4 unprogrammed) und die Bits in WDTCSR
sind alle 0 per default.
Was genau meinst du mit Überlauf? Die Indices i und j in
lcd_buffer[i][j] laufen nie über den definierten Bereich raus, das habe
ich mittels UART geprüft, siehe das Codeschnipsel im ersten Beitrag.
Gibt's sonst noch Ideen?
danke
riz
riz schrieb:> mir ist schon klar wie groß das array lcd_byte ist, deshalb habe ich ja> auch einen Mega128 genommen.
Der Mega128 hat aber auch nur 4KB RAM. Dein lcd_buffer[][] ist größer.
Dabei ist der Verbrauch für die anderen Sachen und Stack noch nichtmal
eingerechnet.
Edit: Ich sehe gerade im OP steht "ATMega1284P". Bei dem sollte sich das
ausgehen...
riz schrieb:> Gibt's sonst noch Ideen?
Mach mal lcd_buffer deutlich größer und initialisier alle mit einem
Codewort, z.B. 0xCAFEAFFE.
Bau einen kleine Checkroutine ein, die prüft, ob in dem Bereich jenseits
der normalen Größe von lcd_buffer dieser Code überschrieben wurde.
Ahhh, da kommen wir der Sache schon näher.
Hab mir per Excel eine Array-Belegung gestrickt, die aufsteigende Zahlen
in der Spalte und Zeile hat. (siehe Definition lcd_buffer im Anhang).
Dann per UART jedes Element anzeigen lassen
1
for(i=0;i<YPIXEL/4+1;i++){
2
for(j=0;j<XPIXEL+15;j++){
3
printf("i %d",i);
4
printf("j %d",j);
5
printf("b %d\n",lcd_buffer[j][i]);
6
}
7
}
und siehe da, es gibt bei j=146 ein Problem für jedes i. Ausschnitt aus
dem Terminal :
(bis da ist alles o.k.)
i 0j 145b 146 (das passt noch, soll 146 sein)
i 0j 146b 99 (das ist Müll, soll 147 sein)
i 0j 147b 0 (das ist Müll, soll 148 sein)
i 0j 148b 16 (das ist Müll, soll 149 sein)
i 0j 149b 150 (das passt wieder, soll 150 sein)
(ab da ist wieder alles o.k.)
D.h. immer die Indices j=146 bis 148 verlieren ihren Wert, egal für
welches i.
Und jetzt???
riz schrieb:> Und jetzt???
Die Arraybelegung so lassen und an verschiedenen Stellen im Programm
mittels if überprüfen und bei Fehler eine Meldung ausgeben. Vielleicht
kann man die Sache so eingrenzen. Alternativ das ganze Programm mal für
PC umschreiben und durch einen guten Debugger jagen (der von MS soll ja
ganz gut für solche Speichergeschichten sein?) und gucken ob das
Programm irgendwo Mist baut.
hallo troll
hab das mal umgesetzt mit dem Anzeigen an versch. Positionen. Leider
hilft's nicht weiter, weil sofort nach der Init-Routine des UART der
Fehler schon da ist und das ist die 2. Zeile im Hauptprogramm :-((
Ich hab mich dazu entschlossen das Problem zu umschiffen indem ich den
lcd_buffer gar nicht mehr benutze (und auch nicht definiere) und halt
alles im Display überschreibe. Ist nicht schön, aber für meine Zwecke
geht's gerade. Resignation pur...
danke an alle die bisher mitgeholfen haben.
Schuss ins Blaue: Könnte es sein dass der verwendete µC einfach nicht
genug RAM hat? Eventuell den Code mal für PC umschreiben und gucken ob
da alles läuft?
riz schrieb:> weil sofort nach der Init-Routine des UART der> Fehler schon da ist
ISt doch schon mal was.
Prüf es doch davor und setze eine LED je nach Zustand.
In Deiner RS232.c fällt mir im Init folgendes auf:
1
stdout=&uart_str;
Vielleicht hast Du hier einen amoklaufenden Zeiger?