Forum: Mikrocontroller und Digitale Elektronik LCD zeigt 4 Balken an


von Matthias (Gast)


Lesenswert?

Egal was ich mache na meinem LED Display erscheinen nach der 
Initalisierung beim senden von Daten immer das Zeichen:

     _
     _
     _
     _

von Matthias (Gast)


Lesenswert?

Geht um dat Ding:

LCD-Modul TC1602A-08 von Pollin

verwende die Funktionen vom Tutorial

von MeinerEiner (Gast)


Lesenswert?

Was denn nun? Balken oder '_'?
Wenns nur __ sind, dann stimmt was am Programm nicht.
Wenns wirklich Balken sind (d.h. alle Pixel sind schwarz), dann ist 
der Kontrast zu hoch.

von Matthias (Gast)


Lesenswert?

"_" diese hier
und der Cursor startet immer am Ende der ersten Zeile

von Matthias (Gast)


Lesenswert?

Ich habe irgendwie das Gefühl, dass in dem ATMEGA8 die FuseBits noch 
falsch gesetzt sind. Habe folgende Port Belegung für den 4 Bit Modus:

#define LCD_RS_PORT    PORTB
#define LCD_RS_DDR    DDRB
#define LCD_RS_NR    0
#define LCD_RS_PIN    PB0

#define LCD_EN_PORT    PORTD
#define LCD_EN_DDR    DDRD
#define LCD_EN_NR    7
#define LCD_EN_PIN    PD7

#define LCD_DATA_4_PORT    PORTD
#define LCD_DATA_4_DDR    DDRD
#define LCD_DATA_4_NR    6
#define LCD_DATA_4_PIN    PD6

#define LCD_DATA_5_PORT    PORTD
#define LCD_DATA_5_DDR    DDRD
#define LCD_DATA_5_NR    5
#define LCD_DATA_5_PIN    PD5

#define LCD_DATA_6_PORT    PORTD
#define LCD_DATA_6_DDR    DDRD
#define LCD_DATA_6_NR    4
#define LCD_DATA_6_PIN    PD4

#define LCD_DATA_7_PORT    PORTD
#define LCD_DATA_7_DDR    DDRD
#define LCD_DATA_7_NR    3
#define LCD_DATA_7_PIN    PD3

von Matthias (Gast)


Lesenswert?

Boah ich könnte druchdrehen, alle PINS haben die richtigen Zustände, 
alle Verbindungen passen, nur das Display schreibt nur ein Zeichen

von Matthias (Gast)


Lesenswert?

Also die Routinen funktionieren auf zwei anderen Displays wunderbar, nur 
bei dem Sch.. Ding nicht:



#include <avr/io.h>
#include "lcd.h"
#include "mydefs.h"
#include <util/delay.h>

// sendet ein Datenbyte an das LCD

void LCD_data(unsigned char temp1)
{
   unsigned char temp2 = temp1;

   LCD_rs_enable();              // RS auf 1 setzen

   temp1 = temp1 >> 4;
   temp1 = temp1 & 0x0F;

   LCD_write_in_ports(temp1);

   LCD_enable();

   temp2 = temp2 & 0x0F;

   LCD_write_in_ports(temp2);

   LCD_enable();

   _delay_us(42);
}

// sendet einen Befehl an das LCD

void LCD_command(unsigned char temp1)
{
   unsigned char temp2 = temp1;

   LCD_rs_disable();            // RS auf 0 setzen

   temp1 = temp1 >> 4;              // oberes Nibble holen
   temp1 = temp1 & 0x0F;            // maskieren

   LCD_write_in_ports(temp1);

   LCD_enable();

   temp2 = temp2 & 0x0F;            // unteres Nibble holen und 
maskieren

   LCD_write_in_ports(temp2);

   LCD_enable();

    _delay_us(42);
}

// erzeugt den Enable-Puls
void LCD_enable(void)
{
   // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
einfügen
   // Beitrag "Re: Bitte helft mir. Schon wieder AtMega16"
   sbi(LCD_EN_PORT,LCD_EN_NR);
    _delay_ms(10);                   // kurze Pause
   // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
verlängern
   // Beitrag "LCD -> Probleme mit Optimierungsgrad"
   cbi(LCD_EN_PORT,LCD_EN_NR);
}

// Initialisierung:
// Muss ganz am Anfang des Programms aufgerufen werden.

void LCD_init(void)
{

   // Alle LCD PORTS auf Ausgang schalten
   sbi(LCD_RS_DDR,LCD_RS_NR);
   sbi(LCD_EN_DDR,LCD_EN_NR);
   sbi(LCD_DATA_4_DDR,LCD_DATA_4_NR);
   sbi(LCD_DATA_5_DDR,LCD_DATA_5_NR);
   sbi(LCD_DATA_6_DDR,LCD_DATA_6_NR);
   sbi(LCD_DATA_7_DDR,LCD_DATA_7_NR);

   // muss 3mal hintereinander gesendet werden zur Initialisierung

    _delay_ms(15);

   // Schreiben einer 0x03
   LCD_write_in_ports(0x03);

   LCD_rs_disable();

   LCD_enable();

   _delay_ms(5);
   LCD_enable();

   _delay_ms(1);
   LCD_enable();
   _delay_ms(1);

   // 4 Bit Modus aktivieren
   LCD_enable();
   _delay_ms(1);

   // 4Bit  2 Zeilen  5x7
   LCD_command(0x28);

   // Display ein  Cursor aus  kein Blinken
    LCD_command(0x0C);

   // inkrement / kein Scrollen
    LCD_command(0x06);

    LCD_clear();
}

// Sendet den Befehl zur Löschung des Displays

void LCD_clear(void)
{
   LCD_command(CLEAR_DISPLAY);
   _delay_us(100);
}

// Sendet den Befehl: Cursor Home

void LCD_home(void)
{
   LCD_command(CURSOR_HOME);
   _delay_ms(100);
}

// setzt den Cursor in Zeile y (1..4) Spalte x (0..15)

void LCD_set_cursor(unsigned char x, unsigned char y)
{
  unsigned char tmp=0;

  switch (y) {
    case 1: tmp=0x80+x; break;    // 1. Zeile
    case 2: tmp=0xC0+x; break;    // 2. Zeile
    case 3: tmp=0x94+x; break;    // 3. Zeile
    case 4: tmp=0xD4+x; break;    // 4. Zeile
  }
  LCD_command(tmp);
}

// Schreibt einen String auf das LCD

void LCD_string(char *data)
{
    while(*data) {
        LCD_data(*data);
        data++;
    }
}
void LCD_rs_enable(void)
{
  sbi(LCD_RS_PORT,LCD_RS_NR);
}
void LCD_rs_disable(void)
{
  cbi(LCD_RS_PORT,LCD_RS_NR);
}

void LCD_write_in_ports(unsigned char data)
{
  unsigned char i = 0, data_temp=0;

  while(i < 4)
  {
    data_temp = data;
    data_temp = data_temp >> i;
    data_temp &= 0x01;
    if(data_temp && (i == 0))   sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
    else            cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);

    if(data_temp && (i == 1))  sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
    else            cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);

    if(data_temp && (i == 2))  sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
    else            cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);

    if(data_temp && (i == 3))  sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);
    else            cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);

    i++;
  }
}

von Matthias (Gast)


Lesenswert?

Vielleicht hilft das noch weiter, wenn die Initialisierungsroutine 
durchgelaufen ist, dann steht der Cursor in der ersten Zeile an der 
letzten Stelle blinkend. Wenn ich den Kontrast erhöhe, wird die erste 
Zeile mit schwarzen Balken gefüllt. Die Initioalisierung auf den 4 Bit 2 
Zeilen 16 Zeichen funktioniert so gar nicht.

von Matthias (Gast)


Lesenswert?

So nun habe ich ein Electronic Assemblys LCD drangehängt.
Selbes Problem. Kann mir denn keiner weiterhelfen?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Vermutlich ne kurzschluß zwischen zwei Signalleitungen, Flasche 
Taktfrequenz oder ein Software/Verdrahtungsfehler.

von Klaus (Gast)


Lesenswert?

cbi(LCD_EN_DDR,LCD_RW_NR);

Solltest auch noch hinzufügen. Wenn RW irgendwo ausversehen gestzt wird 
könnte es auch zu Problemen kommen.

Ansonsten liegt das am richtigen Timing würde ich sagen. Busy Flag wird 
ja nicht abgefragt.

von Matthias (Gast)


Lesenswert?

Also RW ist auf Masse gelegt. Kurzschluss zwischen den Signalleitungen 
habe ich nicht, Softwareverdrahtungsfehler ist auszuschließen, bereits 
1000 mal überprüft, an der Hardware und an der Software. Beim Electronic 
Assemblies schreibt er immer dieses Zeichen "|||".

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Wenn alles okay ist müßte es ja funktionieren...
Zeig doch mal den gesamten Quellcode, hast du die Delays mal verlängert?

von Pete K. (pete77)


Lesenswert?

Schreibst Du auch 3-mal die 0x03 am Anfang in der Init ?

von Karl H. (kbuchegg)


Lesenswert?

So ein ähnliches 'Problem' hatte ich vor kurzem auch an einem LCD.
Mein Problem war, dass ich die Datenleitungen am LCD an D0 bis D3 
anstelle von D4 bis D7 angelötet habe.

Im Nachhinein war ich verblüfft, das das LCD überhaupt initialisiert 
wurde, aber das wurde es zweifellos. Aber anstelle von Zeichen kamen bei 
einem Test nur lauter ausgefüllte Rechtecke zum Vorschein.

von Matthias (Gast)


Lesenswert?

Danke für die Anmerkungen,

da das Ding immer nur die selben Zeichen schreibt, egal welches Zeichen 
ich schicke, gehe ich von einem Hardwarefehler aus. Also habe ich 
zunächst überprüft ob Kurzschlüsse zwischen den Signalleitungen sind. 
Dann habe ich die einzelnen Verbindungen vom Steckverbinder des LCD zum 
uC gemessen und vom Steckverbinder zu den Anschlüssen am LCD. Dann habe 
ich mal die Funktion

LCD_write_in_ports(0x03) am Steckverbinder nachgemessen:

DB4 = 1,2 V
DB5 = 1,2 V
DB6 = 0 V
DB7 = 0 V

Das habe ich variiert, die Bits werden richtig geschrieben.
Dann habe ich die Delayzeiten hochgeschraubt.

Habe das alles nun mit drei Pollin Displays und mit einem Electronic 
Assembly Display durchgeführt. Der Cursor springt immer in der ersten 
Zeile an die letzte Stelle. Dann werden immer die selben Zeichen "|||" 
geschrieben.

Die Belegung der Pins habe ich wie folgt gemacht:

PIN 1 = GND
PIN 2 = VCC
PIN 3 = Schleifer von Poti zw. Vcc und GND
PIN 4 = RS = PB0
PIN 5 = R/W = GND
PIN 6 = EN = PD7
PIN 7 bis PIN10 = offen
PIN 11 = PD6
PIN 12 = PD5
PIN 13 = PD4
PIN 14 = PD3
PIN 15 = VCC
PIN 16 = 330 Ohm -> GND

Welche Infos benötigt ihr noch? Vielen Dank für die Hilfe.

von holger (Gast)


Lesenswert?

void LCD_clear(void)
{
   LCD_command(CLEAR_DISPLAY);
   _delay_us(100);
}

Das delay fürs löschen ist viel zu klein.

von Hannes Lux (Gast)


Lesenswert?

> PIN 11 = PD6
> PIN 12 = PD5
> PIN 13 = PD4
> PIN 14 = PD3

Hmmm, nicht umgekehrt?

...

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

1,2V erscheint mir auch nicht richtig, bei High sollte er 5V ausgeben!

von Matthias (Gast)


Lesenswert?

In Verbindung mit der Funktion LCD_write_in_ports(); und der Header 
Definitionen müsste

> PIN 11 = PD6
> PIN 12 = PD5
> PIN 13 = PD4
> PIN 14 = PD3


korrekt sein.

von Matthias (Gast)


Lesenswert?

So nun tut sich folgendes:

Ich schreibe nach der Initialisierung eine 0x03 mit der Funktion 
LCD_write_in_ports(); dann kann ich am Steckverbinder an den Ports

DB4 = 1,2 V
DB5 = 1,2 V
DB6 = 0 V
DB7 = 0 V

die Spannungen messen.

Schreibe ich nun danach ein LCD_enable() ohne das Display am 
Steckverbinder zu haben, liegen an allen Ports nur

DB4 = 0 V
DB5 = 0 V
DB6 = 0 V
DB7 = 0 V

an. Irgendetwas stimmt also mit der Enable Leitungen oder dem Code 
nicht.

von holger (Gast)


Lesenswert?

>   // 4 Bit Modus aktivieren

Da fehlt doch was?

>   LCD_enable();
>   _delay_ms(1);

So wie ich das sehe schreibst du viermal 0x03.
Und damit bist du im 8 Bit Mode.

von Pete K. (pete77)


Lesenswert?

Es ist Zeit für den Schaltplan bzw. das Boardlayout ...

von Matthias (Gast)


Lesenswert?

Also wenn ich die Ports einzeln high setze mit der Funktion sbi(...) 
kommen da immer korrekte 5 V an. Nehme ich die write_in_ports() kommen 
da 1,2 V bei High an und wenn ich nach der write_in_ports ein enable 
mache, dann liegen nur 0 V an. Irgendwas stimmt komischerweise mit den 
Funktionen nicht.

von Matthias (Gast)


Lesenswert?

Habs raus:

void LCD_write_in_ports(unsigned char data)
{
  unsigned char i = 0, data_temp=0;

  while(i < 4)
  {
    data_temp = data;
    data_temp = data_temp >> i;
    data_temp &= 0b00000001;

    if(data_temp)
    {
      if(i == 0)  sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
      if(i == 1)  sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
      if(i == 2)  sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
      if(i == 3)  sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);
    }
    else
    {
      if(i == 0)  cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
      if(i == 1)  cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
      if(i == 2)  cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
      if(i == 3)  cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);
    }
    i++;
  }
}

keine Ahnung warum, für mich ist die Logik die selbe

von holger (Gast)


Lesenswert?

>keine Ahnung warum, für mich ist die Logik die selbe

Ist sie aber nicht ;)
Wenn i für den entsprechenden Pin nicht ==x ist
wird das else ausgeführt.

von holger (Gast)


Lesenswert?

Mach das doch ohne Schleife dann sparst du Code:
1
void LCD_write_in_ports(unsigned char data)
2
{
3
4
    if(data & 0x01)   sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
5
    else cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
6
7
    if(data & 0x02))  sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
8
    else            cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
9
10
    if(data & 0x04)  sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
11
    else            cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
12
13
    if(data & 0x08)  sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);
14
    else            cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);
15
16
}

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.