Forum: Mikrocontroller und Digitale Elektronik lcd zeigt nur schwarze balken


von dare (Gast)


Lesenswert?

Hi!
Ich habe schon ordentlich gegoogelt aber leider nicht wirklich was 
gefunden.
Ich bin Anfänger und habe ein ANAG VISION AV1624 LCD Display an einen 
Atmega32 angeschlossen. Kontrast geht über 10k Poti.
Ich benutze Fleurys lib und den Port D.
Die Pins habe ich schon zehn mal geprüft. Am LCD liegt alles 
enstprechend der LCD.h.
Probiert habe ich es mit externem Quarzsoszi 4mhz (btw, welche 
Einstellung im AVRStudio für die Fuses?) sowie internem Takt (1mhz).
Das LCD zeigt je nach Kontrast nichts oder die rechte Hälfte des 
Displays mit schwarzen Balken gefüllt an.
Die Pins des Ports D führen mal 5v mal 2v und mal nix.

die c-datei:

#include "lcd.h"


int main(void)
{
  lcd_init(LCD_DISP_ON);
  lcd_clrscr();
  lcd_puts("help me");
  for(;;)
  {
  }
}



lcd.h:

...
#define XTAL 4000000
...
#define LCD_CONTROLLER_KS0073 0
...
#define LCD_PORT         PORTD        /**< port for the LCD lines   */
#define LCD_DATA0_PORT   LCD_PORT     /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT   LCD_PORT     /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT   LCD_PORT     /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT   LCD_PORT     /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN    0            /**< pin for 4bit data bit 0  */
#define LCD_DATA1_PIN    1            /**< pin for 4bit data bit 1  */
#define LCD_DATA2_PIN    2            /**< pin for 4bit data bit 2  */
#define LCD_DATA3_PIN    3            /**< pin for 4bit data bit 3  */
#define LCD_RS_PORT      LCD_PORT     /**< port for RS line         */
#define LCD_RS_PIN       4            /**< pin  for RS line         */
#define LCD_RW_PORT      LCD_PORT     /**< port for RW line         */
#define LCD_RW_PIN       5            /**< pin  for RW line         */
#define LCD_E_PORT       LCD_PORT     /**< port for Enable line     */
#define LCD_E_PIN        6            /**< pin  for Enable line     */
...


Die Data-Pins sind an D4-D7 am Display.

Kann mir jemand nen Tipp geben? Muss ich irgendwelche Fuses setzen oder 
so?
Danke!


Build started 22.5.2008 at 21:32:11
avr-gcc.exe  -mmcu=atmega32 -Wall -gdwarf-2 -Os -std=gnu99 
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP 
-MT lcd.o -MF dep/lcd.o.d  -c  ../lcd.c
avr-gcc.exe -mmcu=atmega32 -Wl,-Map=vescomnew.map vescomnew.o lcd.o 
-o vescomnew.elf
avr-objcopy -O ihex -R .eeprom  vescomnew.elf vescomnew.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" 
--change-section-lma .eeprom=0 --no-change-warnings -O ihex 
vescomnew.elf vescomnew.eep || exit 0
avr-objdump -h -S vescomnew.elf > vescomnew.lss

AVR Memory Usage
----------------
Device: atmega32

Program:     606 bytes (1.8% Full)
(.text + .data + .bootloader)

Data:         18 bytes (0.9% Full)
(.data + .bss + .noinit)


Build succeeded with 0 Warnings...

von Otto (Gast)


Lesenswert?

Hallo dare,

1. hast Du bei internem Takt auch die Zeile: #define XTAL 4000000 
angepasst ?
2. Die unbenutzten Displayleitungen D0-D3 müssen bei einigen Displays 
auf +5V gelegt werden.

Gruss Otto

von dare (Gast)


Lesenswert?

Die Zeile war bei internem Takt angepasst. Ich hatte die Leitungen schon 
mal probehalber auf GND. Hab sie grad auf VCC gelegt - passiert leider 
nichts. Aber danke soweit!

von Otto (Gast)


Lesenswert?

Hallo Dare,

bist Du sicher, dass der Controller läuft ?
Toggle doch mal zusätzlich eine LED.....

Otto

von dare (Gast)


Lesenswert?

Ja er scheint zu laufen. Ich hab nen Messgerät auf PIN0 von Port A 
gehalten und ihn high geschaltet. Kommen 5V raus.
Wenn ich dann nach dem lcd-Kram noch den Pin1 high schalte, so passiert 
nix.

DDRA = (1 << DDA0);
PORTA |= (1<<PA0);              ->PA0 ist high
lcd_init(LCD_DISP_ON);
lcd_clrscr();
lcd_puts("HELPME!!");
DDRA = (1 << DDA1);
PORTA |= (1<<PA1);               ->PA1 bleibt low
  for(;;)
  {
  }

Für mich heisst das, der Atmega hängt sich dazwischen auf, oder?

von holger (Gast)


Lesenswert?

>Für mich heisst das, der Atmega hängt sich dazwischen auf, oder?

Vermutlich.

Pack das mal Step bei Step von hinten angefangen in die LCD Routinen

>PORTA |= (1<<PA1);               ->PA1 bleibt low

Irgendwann weisst du dann wo es hängt.

von dare (Gast)


Lesenswert?

Gute Idee. Die böse Zeile heisst:

 lcd_command(LCD_FUNCTION_DEFAULT);      /* function set: display lines 
*/

Die Funktion sieht so aus:

void lcd_command(uint8_t cmd)
{
    lcd_waitbusy();
    lcd_write(cmd,0);
}

Hier ist das Problem waitbusy()

Ich schaue morgen mal weiter.
Danke und Grüße!

von Otto (Gast)


Lesenswert?

ja, ja, das Busyflag funktioniert bei manchen Displays gar nicht......

Gruss Otto

von dare (Gast)


Lesenswert?

Hmm... Ich muss jetzt zur Uni. Später setz ich mich noch mal ran.
Könnte es klappen, indem ich die Funktion waitbusy() ändere? Ich könnte 
ja einfach einen delay einbauen?
Grüße!

von marvin m. (Gast)


Lesenswert?

Jepp, das würde den Fehler einkreisen.

von dare (Gast)


Lesenswert?

Ich habe alle waitbusys mit delays augetauscht. Das Programm hängt sich 
jetzt immerhin nicht mehr auf. Das Display zeigt nun weniger schwarze 
Balken (so 2,5 pro Zeile, immer noch rechts).
Ich habe die Befürchtung, das Display könnte einfach hin sein.
Was meint ihr? Hab neue bestellt. Mal sehen, wann die kommen.
Grüße!

von Pete K. (pete77)


Lesenswert?

Hier meine Anregungen zur Fehlersuche:

- Init-Sequenz gemäß Datenblatt benutzt
- delay-Funktionswerte im gültigen Bereich (siehe delay.h)
- R/W Leitung korrekt angeschlossen
- Fuses richtig gesetzt
- Kontrast richtig eingestellt
- Startup-Time des Displays abgewartet
- korrekte Spannungen am Display gemessen

So schnell geht ein Dislpay nicht kaputt :-)

Poste mal Dein Programm.

von dare (Gast)


Lesenswert?

Hier meine Anregungen zur Fehlersuche:

- Init-Sequenz gemäß Datenblatt benutzt - wird probiert.

- delay-Funktionswerte im gültigen Bereich (siehe delay.h) -??? ich 
versteh nur Bahnhof ;)

- R/W Leitung korrekt angeschlossen - jawoll

- Fuses richtig gesetzt - ich weiss nicht so recht... jtagen und spien 
sind gesetzt, ocden, ckopt, eesave, bootrst, und boden nicht.

- Kontrast richtig eingestellt - ich dreh am poti und da ändert sich was 
;)

- Startup-Time des Displays abgewartet - das macht die lib selbst. hab 
aber mal nen delay eingebaut. half nix.

- korrekte Spannungen am Display gemessen - alles fein

So schnell geht ein Dislpay nicht kaputt :-)
- hoffen wir, dass es das nicht schon war

Poste mal Dein Programm.
-hab ich oben. ist minimal. nur die lib, die ini, clearscreen, puts.

Grüße!

von dare (Gast)


Angehängte Dateien:

Lesenswert?

Das ist ein Screenshot aus dem Datasheet. Sieht mir so aus, als wenn 
Fleury das alles richtig macht. Das Problem ist aber wie gesagt das 
warten aufs Busy Flag...

von Pete K. (pete77)


Lesenswert?

Hier die Beschränkungen der delay.h Funktionen:

/**
   \ingroup util_delay

   Perform a delay of \c __ms milliseconds, using _delay_loop_2().

   The macro F_CPU is supposed to be defined to a
   constant defining the CPU clock frequency (in Hertz).

   The maximal possible delay is 262.14 ms / F_CPU in MHz.
 */
void
_delay_ms(double __ms)

Wenn Du nicht mehr als 16ms als Argument angibts, bist Du auf der 
sicheren Seite (bis 16Mhz). Ähnliches gilt für _delay_us. Schau mal in 
die Datei c:\WinAVR\avr\include\util\delay.h

Poste trotzdem mal den kompletten Source-Code (als zip).

von dare (Gast)


Angehängte Dateien:

Lesenswert?

Hab grad das gesamte INIT selbst gemacht (gemäß datasheet). Hat nix 
gebracht. Hier ist ein .zip des Projektordners+exportiertes makefile.
Danke und Grüße!

von Sam S. (sammy-1)


Lesenswert?

Ich hatte mal ein ähnliches Problem mit schwarzen Balken. Damals hatte 
ich die restlichen Pins im 4-Bit Mode (D0-D3) auf HIGH gelegt.
Als ich irgendwann mal versucht habe sie einfach nicht zu beschalten, 
klappte alles plötzlich ohne Probleme! Vielleicht mal ausprobieren!

Gruß,
Sammy-1

von dare (Gast)


Lesenswert?

Danke. Aber wie oben schon steht hatte ich sie bereits auf GND, auf VCC 
und nun wieder unbeschaltet. Grüße!

von Pete K. (pete77)


Lesenswert?

Überprüfe bitte noch einmal den RS Anschluss.

Du hast einen 4 Mhz Quarz angeschlossen. Funktioniert ein toggeln der 
LED ?
(Möchte nur ausschließen, dass der Controller falsch angeschlossen ist.)

Hast Du an PortD eine RS232 angeschlossen ?

Mach mal folgendes in main:

#include <avr/delay.h>
...
while (1)
{ LED an
  for (i=0;i<100;i++)
  { _delay_ms(10);
  }
  LED aus
  for (i=0;i<100;i++)
  { _delay_ms(10);
  }
}

von Pete K. (pete77)


Lesenswert?

Wenn Du Busy nicht nutzt und mit delay arbeitest, kannst Du auch RW auf 
GND ziehen. Spart einen PIN am Controller.

von dare (Gast)


Lesenswert?

Wie oben beschrieben kann ich pins high schalten. Habe das an Port A 
gemacht um herauszufinden wos hängen bleibt.
War der wait_busy.
Habe daraufhin die Funktion wie folgt geändert:

original:
static uint8_t lcd_waitbusy(void)
{
    register uint8_t c;
    /* wait until busy flag is cleared */
    while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) {}

    /* the address counter is updated 4us after the busy flag is cleared 
*/
    delay(2);

    /* now read the address counter */
    return (lcd_read(0));  // return address counter

}/* lcd_waitbusy */

jetzt:

static uint8_t lcd_waitbusy(void)

{
    register uint8_t c;

   c=lcd_read(0);
    delay(15000);
    /* now read the address counter */
    return (lcd_read(0));  // return address counter

}/* lcd_waitbusy */


Nun läuft das Programm durch (schalte nen Pin high nachdem der lcd-kram 
durch ist) aber das Display macht nix.
RW habe ich an GND gelegt.

von Pete K. (pete77)


Lesenswert?

Schmeiss mal das lcd_read raus. Du kannst keine read machen, wenn RW auf 
0 gelegt ist. Außerdem wollen wir das ja mit delay machen.

Ersetze delay(15000) durch eine for-schleife 1-1000 mit delay(15)

Ersetze mal für's erste waitbusy mit

static uint8_t lcd_waitbusy(void)
{
    register uint8_t c;

    _delay_ms(15);  // #include <utils/delay.h> nicht vergessen

    return (0);  // return nonsense

}/* lcd_waitbusy */

von dare (Gast)


Lesenswert?

RS hängt am definierten Port. Ich dreh bald durch. Ärgerlich, dass ich 
kein zweites LCD hier habe. Nur um sicher zu gehen...
LCD´s sind bestellt (Ebay) aber noch nicht da. Bei ner Preisdifferenz 
von 14 Euro von Ebay zu Conrad bring ichs nicht fertig mir ncoh eins bei 
Conrad zu kaufen.
Andererseits ist die verlorene Zeit...
Hätte allerdings eh gern eins, das nicht baugleich ist.
Vielleicht häng ich das Display ja noch an nen anderen Port.

von dare (Gast)


Lesenswert?

Hmm... ich glaube, das geht nicht. Weil es doch mit den übergebenen 
Daten weiter geht... Null mag der nicht als Rückgabe...
Ich probiers mal eben an nem anderen Port. Lötkolben liegt ja neben der 
Couch...

von Pete K. (pete77)


Lesenswert?

Nicht aufgeben. Das Display zeigt schwarze Streifen, also scheint es 
noch zu funktionieren.

Mit den neuen Displays wirst Du die gleichen Probleme haben...

Ich richte mir immer eine RS232 Verbindung zum Debuggen ein.

Da kann man auch innerhalb der lcd.h schauen, was passiert.

Tja, µCs zu debuggen ist nicht einfach :-)

Versuch mal alles Lesende durch _delay_ms(15) zu ersetzen.

von dare (Gast)


Lesenswert?

So, an Porta wars das Gleiche. Gute Nacht allerseits!

von Pete K. (pete77)


Lesenswert?

hast Du das waitbusy jezt ersetzt ?

Gute Nacht :-)

von dare (Gast)


Lesenswert?

Hab ich probiert, ja. Hat aber leider nichts gebracht.
Durch das rausnehmen des lcd_read wurde lcd_read gleich überflüssig.
Daran kanns also nicht mehr liegen. Das Programm wird bis zum Ende 
abgearbeitet. Hängt sich also auch nicht auf.
Ich weiss nicht weiter...
Hab grad schon wieder jeden einzelnen Pin auf Durchgang geprüft. Alles 
stimmt. Atmega läuft. Entweder mir fehlt was im makefile, es ist was mit 
den fuses oder irgendetwas anderes, was sich der Aufmerksamkeit eines 
Anfängers verschliesst, wenn er vor AVR Studio sitzt oder das Display 
ist im Sack. Was anderes fällt mir nicht mehr ein.
Ich kann nicht über die serielle Schnittstelle debuggen, da ich keine 
serielle Schnittstelle habe. Ich habe hier zwei Notebooks ohne.
Es gibt wohl die Möglichkeit, meinen Usbprog als Schnittstelle 
einzurichten aber damit habe ich mich noch nicht beschäftigt. Ich 
befürchte auch, mir platzt der Kopf, wenn ich mir das auch noch antue. 
Oder ist das ganz simpel und jemand kanns mir erklären?
Grüße!

von dare (Gast)


Lesenswert?

Neues Display da. Probleme weg. Danke an alle!

von Pete K. (pete77)


Lesenswert?

Na dann herzlichen Glückwunsch :-)

Ich benutze den seriellen AVRISP an USB mit einem RS232<->USB 
Konvertermodul. Kann man auch selber bauen, gibt es aber für 'nen 5er 
auf dem Grabbeltisch.

So sieht das aus: 
http://www.comnations.de/product_info.php?products_id=9307778)

USB 2.0 ist nicht zwingend notwendig, weil die Geschwindigkeit von 
USB1.1 für RS232 ausreicht.

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.