mikrocontroller.net

Forum: Compiler & IDEs Speicherprobleme mit LCD Ansteuerung


Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe mir bei Pollin ein LCD (16x2) bestellt und erfolgreich an 
meinen Atmega8 gehängt. Ich habe mir dazu die LCD Libary von Peter 
Fleury´s verwendet und mir ein kleines Programm mit irgendwelchem 
Beispiel Text geschrieben.

Mittels eines Linux Shell Skriptes lasse kann ich mir einen beliebig 
langen Text in eine Switch Case C Routine automatisch ändern lassen, 
auch das funktioniert wunderbar.

Die einzige Aufgabe meines Atmega ist, mit jeweils 2 Tastern langsames 
Vor- und Rückblättern sowie schnelles Vor- und Rückblättern des Textes 
im Display zu ermöglichen. Dabei habe ich allerdings ein Problem: Sobald 
ich mehr als

Nur ein Problem habe ich: Sobald ich mehr als 29 Case aufrufe 
unterbringen will, ist der Data Speicher zu über 100% gefüllt. Der 
Programmspeicher ist erst zu ca. 25% gefüllt. Ich habe gelesen das 
Statische Strings die nicht verändert werden sollen in das EEPROM 
ausgelagert werden können, wenn ich das richtig sehe, ist dies aber nur 
ein halbes k groß und ich habe leider nirgendwo hinweise darauf gefunden 
wie man das bei der lcd_puts() Funktion machen könnte.

Vielleicht kann mir jemand helfen wie ich diesen C-Code weiter 
optimieren kann so das ich mehr Speicher für den Text zu Verfügung habe.

Vielen Dank im Voraus !!
#include <stdlib.h>
#include <avr/io.h>
#include <inttypes.h>
#include <lcd.h>
#define F_CPU 4000000
#include <util/delay.h>
#include <lcd.c>



int main(void)
{ 
lcd_init(LCD_DISP_ON);    // LCD initialisieren
uint8_t a=0;        // Hilfsvariable a deklarieren
uint8_t x=0;        // Hilfsvariable x deklarieren

while(1)          // Endlos schleife
  {
  x=a;          // x auf den gleichen Wert wie a setzen
  if ( PINB & (1<<PINB1) )
    {
    }
  else
    {
      a--;
      _delay_ms(40);  // 40 ms Warten, mehr oder weniger auch Tasterenprellung (langsam rückwärts blättern)
    }
  
  if ( PINB & (1<<PINB0) )
    {
    }
  else
    {
      a++;
      _delay_ms(40);  // 40 ms Warten, mehr oder weniger auch Tasterenprellung (langsam vorwärts blättern)
    }
  if ( PINB & (1<<PINB2) )
    {
    }
  else
    {
      a--;
      _delay_ms(10);  // 10 ms Warten, mehr oder weniger auch Tasterenprellung (schnell rückwärts blättern)
    }
  
  if ( PINB & (1<<PINB3) )
    {
    }
  else
    {
      a++;
      _delay_ms(10);  // 10 ms Warten, mehr oder weniger auch Tasterenprellung (schnell vorwärts blättern)
    }

  if ( x!=a)        // Wenn a verändert wird, anzeige im Display ändern
    {
    switch (a) 
      { 
      case 0: 
      lcd_clrscr(); 
      lcd_puts("Da die Standard-"); 
      lcd_puts("Shell keine arit"); 
      break; 
      case 1: 
      lcd_clrscr(); 
      lcd_puts("hmetischen oder "); 
      lcd_puts("logischen Ausdrü"); 
      break; 
      case 2: 
      lcd_clrscr(); 
      lcd_puts("cke auswerten ka"); 
      lcd_puts("nn, muss dazu ei"); 
      break; 
      case 3: 
      lcd_clrscr(); 
      lcd_puts("n externes Progr"); 
      lcd_puts("amm benutzt werd"); 
      break; 
      case 4: 
      lcd_clrscr(); 
      lcd_puts("en. (if und Kons"); 
      lcd_puts("orten prüfen nur"); 
      break; 
      case 5: 
      lcd_clrscr(); 
      lcd_puts("den Rückgabewert"); 
      lcd_puts("eines aufgerufen"); 
      break; 
      case 6: 
      lcd_clrscr(); 
      lcd_puts("en Programmes --"); 
      lcd_puts("0 bedeutet true,"); 
      break; 
      case 7: 
      lcd_clrscr(); 
      lcd_puts("alles andere bed"); 
      lcd_puts("eutet false, sie"); 
      break; 
      case 8: 
      lcd_clrscr(); 
      lcd_puts("he auch Rückgabe"); 
      lcd_puts("werte) Dieses Pr"); 
      break; 
      case 9: 
      lcd_clrscr(); 
      lcd_puts("ogramm heißt tes"); 
      lcd_puts("t. Üblicherweise"); 
      break; 
      case 10: 
      lcd_clrscr(); 
      lcd_puts("besteht auf alle"); 
      lcd_puts("n Systemen auch "); 
      break; 
      case 11: 
      lcd_clrscr(); 
      lcd_puts("noch ein Link na"); 
      lcd_puts("mens [ auf diese"); 
      break; 
      case 12: 
      lcd_clrscr(); 
      lcd_puts("s Programm. Dies"); 
      lcd_puts("er Link ist abso"); 
      break; 
      case 13: 
      lcd_clrscr(); 
      lcd_puts("lut gleichwertig"); 
      lcd_puts("zu benutzen. Dem"); 
      break; 
      case 14: 
      lcd_clrscr(); 
      lcd_puts("entsprechend ist"); 
      lcd_puts("es auch zwingend"); 
      break; 
      case 15: 
      lcd_clrscr(); 
      lcd_puts("erforderlich, na"); 
      lcd_puts("ch der Klammer e"); 
      break; 
      case 16: 
      lcd_clrscr(); 
      lcd_puts("in Leerzeichen z"); 
      lcd_puts("u schreiben. Das"); 
      break; 
      case 17: 
      lcd_clrscr(); 
      lcd_puts("dient dazu, Bedi"); 
      lcd_puts("ngungen in if-Ab"); 
      break; 
      case 18: 
      lcd_clrscr(); 
      lcd_puts("fragen u. ä. les"); 
      lcd_puts("barer zu machen."); 
      break; 
      case 19: 
      lcd_clrscr(); 
      lcd_puts("Um dieses Konzep"); 
      lcd_puts("t der Lesbarkeit"); 
      break; 
      case 20: 
      lcd_clrscr(); 
      lcd_puts("zu unterstützen,"); 
      lcd_puts("sollte man diese"); 
      break; 
      case 21: 
      lcd_clrscr(); 
      lcd_puts("öffnende Klammer"); 
      lcd_puts("auch wieder schl"); 
      break; 
      case 22: 
      lcd_clrscr(); 
      lcd_puts("ießen (obwohl da"); 
      lcd_puts("s nicht zwingend"); 
      break; 
      case 23: 
      lcd_clrscr(); 
      lcd_puts("nötig ist). Das"); 
      lcd_puts("test-Programm bi"); 
      break; 
      case 24: 
      lcd_clrscr(); 
      lcd_puts("etet sehr umfang"); 
      lcd_puts("reiche Optionen "); 
      break; 
      case 25: 
      lcd_clrscr(); 
      lcd_puts("an. Dazu gehören"); 
      lcd_puts("Dateitests und V"); 
      break; 
      case 26: 
      lcd_clrscr(); 
      lcd_puts("ergleiche von Ze"); 
      lcd_puts("ichenfolgen oder"); 
      break; 
      case 27: 
      lcd_clrscr(); 
      lcd_puts("ganzen Zahlen. D"); 
      lcd_puts("iese Bedingungen"); 
      break; 
      case 28: 
      lcd_clrscr(); 
      lcd_puts("können auch durc"); 
      lcd_puts("h Verknüpfungen "); 
      break; 
      case 29: 
      lcd_clrscr(); 
      lcd_puts("kombiniert werde"); 
      lcd_puts("n. Dateitests:"); 
      break; 
      
      
      }
    }

  _delay_ms(10);
  }  // While Klamer zu
  

} // Main Klammer zu

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du willst den Text ins Flash auslagern. Davon hast du noch jede Menge. 
Die Fleury Lib unterstützt das auch prächtig mit einem lcd_puts_P, 
sodass du nahezu keine Arbeit damit hast.

NB: Ist es wirklich notwendig, da so kompliziert mit switch-case auf die 
einzelnen Seiten zu gehen. Mann kann doch die Startadresse des ersten 
Buchstabens wunderbar aus der Seitenzahl errechnen. Ebenso weißt du 
wieviele Zeichen du jeweils auszugeben hast. Damit kann man sich auch 
eine spezielle Routine bauen, die
aus der übergebenen Seitenzahl die Startadresse berechnet.
Von dort weg 16 Zeichen ausgibt.
In die nächste LCD Zeile wechselt
und dort nocheinmal 16 Zeichen ausgibt (natürlich nur, wenn auch noch 
wirklich 16 Zeichen vorhanden sind).

-> Dein Anzeigeteil im Programm schrumpft auf 10 Zeilen zusammen. Nicht 
zu verachten der Komfort, der ensteht, wenn du den Text irgendwann 
einmal ändern musst.

lcd_puts_P kannst du dann zwar nicht mehr so direkt nehmen, aber die 
Technik die Zeichen aus dem Flash zu lesen, bleibt die Gleiche.

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also erstmal vielen Dank für den super Tipp! Irgendwie muss ich bei den 
ganzen anderen Problem die ich mit dem LCD usw. hatte die lcd_puts_P() 
Funktion übersehen haben. Hab das Programm gerade geändert und bekomme 
jetzt beim compilieren
AVR Memory Usage
----------------
Device: atmega8

Program:    2088 bytes (25.5% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)


Build succeeded with 0 Warnings...
angezeigt! was schonmal sehr gut ist!! Wann ist denn der Flash Speicher 
voll ? die Daten müssen ja irgendwohin geschrieben werden, aber der 
Compilier zeigt mir nichts an... irgendwie verwirrt mich die ganze Sache 
mit dem Speicher des Mc. Muss ich mich mal in Ruhe mit befassen.

Die Switch Anweisung wird mir mittels eines kleinen Linux Shell skriptes 
erzeugt, also Text unformatiert rein und komplette Switch Case Anwendung 
raus. Dabei werden im Moment schon überflüssige Leerzeichen am 
Zeilenanfang entfernt. Was noch kommen soll ist: ä in ae, Leerzeichen 
nach Punkt oder Komma entfernen usw.... das is aber eine andere 
Baustelle, mit der Shell kann ich wesentlich besser umgehen als mit gcc, 
daher habe ich auch diese Switch Case Lösung gewählt. Was anderes ist 
mir auch gar nicht eingefallen, ich werde deine Idee aber mal 
aufgreifen.

PS: Gerade mal ins Datenblatt des MCT geschaut, versteh ich das richtig 
das ich mich mit meinem Ursprünglichen lcd_puts() nur im SRAM ( 1K ) 
aufgehalten habe und mit lcd_puts_P() im 8K großem Flash befinden ?

Autor: lecroix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hast Du richtig verstanden.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:

> angezeigt! was schonmal sehr gut ist!! Wann ist denn der Flash Speicher
> voll ? die Daten müssen ja irgendwohin geschrieben werden, aber der
> Compilier zeigt mir nichts an...

Doch das tut er.
Deine Texte sind in den 25% enthalten.
Der Grund warum dieser Wert nicht größer geworden ist, ist ganz einfach: 
Die Texte waren auch vorher schon im Flash. Denn irgendwie müssen diese 
Texte ja beim Programmstart auch ins SRAM gelangen. Die sind ja nicht 
von Anfang an dort. Das Runtime System kopiert sie am Programmanfang vom 
Flash in den SRAM von wo sie sich dein Programm dann abgeholt hat. Da du 
die Texte jetzt direkt aus dem Flash holst, besteht auch keine 
Notwendigkeit mehr, sie zunächst ins SRAM umzukopieren.
* der Startvorgang wird schneller
* der SRAM Verbrauch steigt nicht an

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.