Forum: Compiler & IDEs Programm startet neu bei Zugriff auf array


von riz (Gast)


Angehängte Dateien:

Lesenswert?

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
void lcd_clrscr(uint8_t fill)
2
{
3
  uint8_t i,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

von J.-u. G. (juwe)


Lesenswert?

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.

von riz (Gast)


Lesenswert?

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...

von riz (Gast)


Lesenswert?

wie befürchtet : Ersetzen von
1
#define lcd_send_data(data) lcd_send(data, 1)
durch
1
void lcd_send_data (uint8_t data)
2
{
3
  lcd_send(data,1);
4
}
und die entsprechende Definition im header file bringt nix...

von Bronco (Gast)


Lesenswert?

Watchdog?
Überlauf von lcd_buffer[][]?

von Oliver (Gast)


Lesenswert?

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

von riz (Gast)


Lesenswert?

@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

von Thomas M. (thomil)


Lesenswert?

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...

von Bronco (Gast)


Lesenswert?

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.

von riz (Gast)


Angehängte Dateien:

Lesenswert?

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???

von troll (Gast)


Lesenswert?

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.

von riz (Gast)


Lesenswert?

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.

von troll (Gast)


Lesenswert?

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?

von Bronco (Gast)


Lesenswert?

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?

von Klaus D. (kolisson)


Lesenswert?

.. und bei ominösen Neustarts etc. auch immer ein Auge auf den Stack 
werfen.

Gruss K.

von troll (Gast)


Lesenswert?

Klaus De lisson schrieb:
> .. und bei ominösen Neustarts etc. auch immer ein Auge auf den Stack
> werfen.

Jup, daher meine Frage nach dem RAM.

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.