www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD zeigt 4 Balken an


Autor: Matthias (Gast)
Datum:

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

     _
     _
     _
     _

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht um dat Ding:

LCD-Modul TC1602A-08 von Pollin

verwende die Funktionen vom Tutorial

Autor: MeinerEiner (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"_" diese hier
und der Cursor startet immer am Ende der ersten Zeile

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Matthias (Gast)
Datum:

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

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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++;
  }
}

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Matthias (Gast)
Datum:

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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

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

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 "|||".

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

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

Autor: Pete K. (pete77)
Datum:

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

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

Bewertung
0 lesenswert
nicht 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.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void LCD_clear(void)
{
   LCD_command(CLEAR_DISPLAY);
   _delay_us(100);
}

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

Autor: Hannes Lux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> PIN 11 = PD6
> PIN 12 = PD5
> PIN 13 = PD4
> PIN 14 = PD3

Hmmm, nicht umgekehrt?

...

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

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

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Pete K. (pete77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist Zeit für den Schaltplan bzw. das Boardlayout ...

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach das doch ohne Schleife dann sparst du Code:
void LCD_write_in_ports(unsigned char data)
{

    if(data & 0x01)   sbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);
    else cbi(LCD_DATA_4_PORT,LCD_DATA_4_NR);

    if(data & 0x02))  sbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);
    else            cbi(LCD_DATA_5_PORT,LCD_DATA_5_NR);

    if(data & 0x04)  sbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);
    else            cbi(LCD_DATA_6_PORT,LCD_DATA_6_NR);

    if(data & 0x08)  sbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);
    else            cbi(LCD_DATA_7_PORT,LCD_DATA_7_NR);

}



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.