mikrocontroller.net

Forum: Compiler & IDEs LCD-Problem (AVR ATMega644)


Autor: Andreas del Galdo (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein Problem mit einer LCD-Steuerung eines Hitachi-kompatiblen 
LCDs. Im angehängten Code befinden sich in der lcd.c die init(), die 
send_data() und die send_cmd() Funktion. Wenn ich folgendermaßen einen 
String aufs Display bringen möchte funktioniert das wunderbar:
char hallo[lcd_max_col] = {'H','A','L','L','O','\0'};
lcd_send(hallo);  //es erscheint HALLO

Wenn ich jetzt aber mittels
lcd_send("Hallo!");
 Hallo! schreiben möchte, dann erhalten ich nur schwarze Kästchen. Im

Detail ruft die funktion lcd_send() für die größe des Strings die 
lcd_send_data-Funktion auf, die jeweils ein Byte, also ein Char sendet.

Hat einer vielleicht eine Erklärung, warum das so ist? Einen Ansatzpunkt 
wo ich weitersuchen könnte nehme ich auch gern ;)

Danke GALDO

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was erwartet "lcd_send" denn für einen Parameter? Es wird ja vermutlich 
ein Zeiger sein. Aber worauf (v.a. welchen Speicher) zeigt dieser 
Zeiger? Je nach Einstellung werden konstante Strings (wie in der zweiten 
Version) generell im Flash abgelegt. Wenn die Funktion aber einen 
Pointer auf RAM haben möchte, dann knallts. Gibt es beim compilieren der 
zweiten Version keine Warnung?

Autor: Andreas del Galdo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void lcd_send_data(char data) {  
  //set data mode
  PORTD |= (1 << lcd_cmd_rs);
  PORTC = data;
  lcd_enable();
  _delay_ms(10);
}

void lcd_send(char *data) {
  while (*data) {
    lcd_send_data(*data);
    data=data+1;
    _delay_ms(2);
  }
}

die delays sind nur zu Testzwecken mit drin und wahrscheinlich nicht 
nötig ;)

Galdo

Autor: Andreas DG (galdo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Compiler meckert nicht - ist alles "normal"

Galdo

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schön, das Problem dürfte aber tatsächlich darin bestehen, dass "Hallo" 
im Flash abgelegt wird, die Funktion die übergebene Adresse aber als 
RAM-Adresse interpretiert und dementsprechend an der Stelle im RAM 
nichts brauchbares findet, weil der String ja im Flash liegt... Du 
müsstest entweder den String explizit im RAM anlegen (was Du ja in 
Deiner ersten Version machst, was aber Speicherverschwendung ist) oder 
die Funktion so umschreiben, dass sie den übergebenen Parameter "Zeiger 
auf String" als "Zeiger auf String im Flash" interpretiert (und mit 
pgm_read_byte aus der pgmspace.h auf die Elemente zugreift).

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

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:
> Schön, das Problem dürfte aber tatsächlich darin bestehen, dass "Hallo"
> im Flash abgelegt wird

Bei welchem Compiler?
Beim gcc in der Standardeinstellung auf einem AVR wird das
mit Sicherheit nicht gemacht.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Johannes M. wrote:
>> Schön, das Problem dürfte aber tatsächlich darin bestehen, dass "Hallo"
>> im Flash abgelegt wird
>
> Bei welchem Compiler?
> Beim gcc in der Standardeinstellung auf einem AVR wird das
> mit Sicherheit nicht gemacht.
Deshalb schrieb ich ja weiter oben auch "je nach Einstellung". 
Möglicherweise liegt der Hund tatsächlich woanders begraben, aber es 
"riecht" eben genau danach, dass der String irgendwo liegt, wo ihn die 
Funktion mit dem verwendeten Zeiger nicht findet, weil eben eine Adresse 
von Speicher X als Adresse von Speicher Y interpretiert wird.

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

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. wrote:
> Karl heinz Buchegger wrote:
>> Johannes M. wrote:
>>> Schön, das Problem dürfte aber tatsächlich darin bestehen, dass "Hallo"
>>> im Flash abgelegt wird
>>
>> Bei welchem Compiler?
>> Beim gcc in der Standardeinstellung auf einem AVR wird das
>> mit Sicherheit nicht gemacht.
> Deshalb schrieb ich ja weiter oben auch "je nach Einstellung".

Hmm. Hast du eine Idee, welche Option das sein könnte?
Ich hab jetzt mal in der WinAVR-gcc Doku geschmökert,
mir ist aber keine Option aufgefallen, die sowas bewirken
würde.

> Möglicherweise liegt der Hund tatsächlich woanders begraben, aber es
> "riecht" eben genau danach, dass der String irgendwo liegt, wo ihn die
> Funktion mit dem verwendeten Zeiger nicht findet, weil eben eine Adresse
> von Speicher X als Adresse von Speicher Y interpretiert wird.

Geb ich die recht, es riecht tatsächlich danach. Kann
aber eigentlich nicht sein.


Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Hmm. Hast du eine Idee, welche Option das sein könnte?
> Ich hab jetzt mal in der WinAVR-gcc Doku geschmökert,
> mir ist aber keine Option aufgefallen, die sowas bewirken
> würde.
Mir jetzt auch nicht wirklich. Ich glaub ich stecke noch zu sehr in 
anderen Compilern drin (CodeVision), die konstante Strings ohne zu 
zögern ins Flash schreiben...

> Geb ich die recht, es riecht tatsächlich danach. Kann
> aber eigentlich nicht sein.
Ist immer blöd, wenn es zwar die wahrscheinlichste Lösung ist, aber 
andererseits auch wieder nicht sein kann... Dann müssen wir wohl weiter 
suchen.

Autor: Andreas DG (galdo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es muss tatsächlich mit den "" zusammenhängen - ich gehe aber nicht 
davon aus, dass Strings per Standard im Flash gespeichert werden (wär ja 
per se Blödsinn)...

Ich hab also keine Idee :(

Wenn jemand noch nen Geistesblitz hat, bitte her damit. Ich verwenden 
den AVR-GCC in der Version 4.2.0
Es werden eingebaute Spezifikationen verwendet.
Ziel: avr
Konfiguriert mit: ./configure --disable-libssp --enable-languages=c --target=avr --prefix=/usr/local/avr
Thread-Modell: single
gcc-Version 4.2.0

in der avr/version.h steht folgendes:
#ifndef _AVR_VERSION_H_
#define _AVR_VERSION_H_

/** \ingroup avr_version
    String literal representation of the current library version. */
#define __AVR_LIBC_VERSION_STRING__ "1.4.6"

/** \ingroup avr_version
    Numerical representation of the current library version.

    In the numerical representation, the major number is multiplied by
    10000, the minor number by 100, and all three parts are then
    added.  It is intented to provide a monotonically increasing
    numerical value that can easily be used in numerical checks.
 */
#define __AVR_LIBC_VERSION__        10406UL

/** \ingroup avr_version
    String literal representation of the release date. */
#define __AVR_LIBC_DATE_STRING__    "20070514"

/** \ingroup avr_version
    Numerical representation of the release date. */
#define __AVR_LIBC_DATE_            20070514UL

/** \ingroup avr_version
    Library major version number. */
#define __AVR_LIBC_MAJOR__          1

/** \ingroup avr_version
    Library minor version number. */
#define __AVR_LIBC_MINOR__          4

/** \ingroup avr_version
    Library revision number. */
#define __AVR_LIBC_REVISION__       6

#endif /* _AVR_VERSION_H_ */

Danke GALDO

Autor: Andreas DG (galdo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat denn keiner mehr ne Idee :(

Galdo

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du
char hallo[] = "Hallo!";
lcd_send(hallo);
schreibst, dann geht's auch, oder? Poste doch mal das Disassembly von 
beiden Versionen, das sollte Klarheit schaffen.
Die Delays sind übrigens durchaus erforderlich, allerdings nicht in der 
Länge. Siehe Datenblatt des Displays.

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.