www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD Display


Autor: Christian D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

will ein LCD-Display ansteuern, habe nun gerade nach dem Datenblatt die 
Init geschrieben, nun möchte ich mit der schreib Funktion Anfangen.
Nun stehe ich vor einem Problem und zwar muss ich ja zuerst die DD-RAM 
Adresse setzen dazu steht im Datenblatt:
Set DDRAM address: RS = L, RW = L, DB7 = H, DB6 = AC6, DB5 = AC5, DB4 = 
AC4, DB3 = AC3, DB2 = AC2, DB1 = AC1, DB0 = AC0

Also mit L ist ja Low gemeint also 0, mit H High also 1,
nur was soll ich dann bei AC0 - 6 machen? 0 oder 1 ?

Autor: Michael U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

naja, vielleicht Datenblatt auch verstehen? ;-)))

AC6...AC0 ist die gewünschte DDRAM-Adresse, an der Du demnächst ein 
Zeichen anzeigen willst.
Die Zuordnung der Adressen zur Darstellung im Display (Zeile, Position) 
steht auch irgendwo im Datenblatt.
Bei HD44xxx-kompatiblen meist Zeile 1 ab 0x00, Zeile 2 ab 0x40 usw.
0x00 -> 00000000
0x40 -> 01000000
DB0...DB6 davon sind Deine Bits für AC0...AC6.
AC soll wohl Adress-Counter heißen oder so.

Gruß aus Berlin
Michael

Autor: *.* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AC0 - 6 ist die Adresse.

DB7,DB6,......,DB0
1,0,0,0,0,0,0,0 für Adresse 0,
1,0,0,0,0,0,0,1 für Adresse 1 usw.

Autor: Christian D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
achso ok, ich hab das jetzt so gemacht, es wird aber nichts angezeigt, 
ist das so überhaupts richtig?


// set DD-RAM address
PORTD |= (0 << E);
PORTD |= (0 << RS);
PORTD |= (0 << RW);

PORTB |= (1 << D0);
PORTB |= (0 << D1);
PORTB |= (0 << D2);
PORTB |= (0 << D3);
PORTB |= (0 << D4);
PORTB |= (0 << D5);
PORTD |= (0 << D6);
PORTD |= (1 << D7);


// write data
PORTD |= (0 << E);
PORTD |= (1 << RS);
PORTD |= (0 << RW);

PORTB |= (0 << D0);
PORTB |= (0 << D1);
PORTB |= (0 << D2);
PORTB |= (0 << D3);
PORTB |= (0 << D4);
PORTB |= (0 << D5);
PORTD |= (0 << D6);
PORTD |= (1 << D7);

PORTD |= (1 << E);

Autor: *.* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann die Fliege auch mit dem Elefanten erschlagen ;)

E muss ein- und  wieder ausgeschaltet werden nachdem das Datenbyte 
angelegt wurde. Dann muss eine Pause mindestens 40µs, sehr wichtig, 
folgen.

Autor: Johannes A. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ich nicht verstehe:

DIESE Frage wird hier im Forum doch inzwischen so zirke 5mal pro Woche 
gestellt. Und immer wieder geduldig von irgendjemandem beantwortet.

Ich habe dazu selber schon einen kompletten funktionierenden Code 
gepostet.

Aber trotzdem, immer wieder neu: "Wie geht LCD-Ansteuerung?"

Meine Antwort: Ohne RTFM und für 2Cent Phantasie sowieso nicht.

Und keine Bange, ich werde mich nie wieder in dieses Thema einschalten.

Gruß Johannes

Autor: Christian D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry aber wenn mir das alles nicht weiterhilft?

hier mein quelltext:

#include <avr/io.h>
#include <uart.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <util/delay.h>  // headerdatei für _delay_ms();
#include <avr/wdt.h>  // headerdatei für watchdog
#include "main.h"

#define SYSCLK    3686400UL  //3686400 8000000
#define BAUD    300UL
#define UBRR_BAUD  ((SYSCLK/(16*BAUD))-1)
#define VCC 5

//#define ADC_VREF_TYPE 0x00  //External VREF
//#define ADC_VREF_TYPE 0x40  //AVCC
#define ADC_VREF_TYPE 0xc0  //Interne 2,56V Spannung

#define D0 PB0
#define D1 PB1
#define D2 PB2
#define D3 PB3
#define D4 PB4
#define D5 PB5
#define D6 PD6
#define D7 PD7

#define RS PD4
#define RW PD3
#define E  PD2

int crash;
int light;
int wert;
double temp;

int count = 0;
int sec = 0;
int min = 42;
int hour = 20;
int day = 0;
int month = 0;

ISR( TIMER0_OVF_vect )
{
  count++;
  if (count == 1800) {  // (Takt / 8) / 256
  sec++;
  count = 0;
  if (sec == 60) {
  min++;
  sec = 1;
  }
  if (min == 60) {
  hour++;
  min = 0;
  }
  if (hour == 24) {
  day++;
  hour = 1;
  }
  if (day == 30) {
  month++;
  day = 1;
  }
  }
}



int main(void)
{

int status = 0;


// LCD Init Start

DDRB = 0xff; // PORTB als Ausgang
DDRD = 0xff; // PORTD als Ausgang

// Function Set
PORTD |= (0 << E);
PORTD |= (0 << RS);
PORTD |= (0 << RW);

PORTB |= (0 << D0);
PORTB |= (0 << D1);
PORTB |= (1 << D2); // Display On
PORTB |= (0 << D3); // 1 Line Mode
PORTB |= (1 << D4);
PORTB |= (1 << D5);
PORTD |= (0 << D6);
PORTD |= (0 << D7);
_delay_us(40);

// Display On
PORTD |= (0 << E);
PORTD |= (0 << RS);
PORTD |= (0 << RW);

PORTB |= (1 << D0);
PORTB |= (1 << D1);
PORTB |= (1 << D2);
PORTB |= (1 << D3);
PORTB |= (0 << D4);
PORTB |= (0 << D5);
PORTD |= (0 << D6);
PORTD |= (0 << D7);
_delay_us(40);

// Display clear
PORTD |= (0 << E);
PORTD |= (0 << RS);
PORTD |= (0 << RW);

PORTB |= (1 << D0);
PORTB |= (0 << D1);
PORTB |= (0 << D2);
PORTB |= (0 << D3);
PORTB |= (0 << D4);
PORTB |= (0 << D5);
PORTD |= (0 << D6);
PORTD |= (0 << D7);
_delay_ms(2);

// Entry mode set
PORTD |= (0 << E);
PORTD |= (0 << RS);
PORTD |= (0 << RW);

PORTB |= (1 << D0);
PORTB |= (1 << D1);
PORTB |= (1 << D2);
PORTB |= (0 << D3);
PORTB |= (0 << D4);
PORTB |= (0 << D5);
PORTD |= (0 << D6);
PORTD |= (0 << D7);
_delay_us(40);

// Init Ende

while (status == 0)
{

// set DD-RAM address
PORTD |= (0 << E);
PORTD |= (0 << RS);
PORTD |= (0 << RW);

PORTB |= (1 << D0);
PORTB |= (0 << D1);
PORTB |= (0 << D2);
PORTB |= (0 << D3);
PORTB |= (0 << D4);
PORTB |= (0 << D5);
PORTD |= (0 << D6);
PORTD |= (1 << D7);
_delay_us(40);

// write data
PORTD |= (0 << E);
PORTD |= (1 << RS);
PORTD |= (0 << RW);

PORTB |= (0 << D0);
PORTB |= (0 << D1);
PORTB |= (0 << D2);
PORTB |= (1 << D3);
PORTB |= (0 << D4);
PORTB |= (0 << D5);
PORTD |= (1 << D6);
PORTD |= (1 << D7);
_delay_us(44);

PORTD |= (1 << E);
PORTD &= ~( 1 << E);

_delay_us(40);

}
// Schleifen Ende

}

Autor: Michael U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

@Johannes A.:
ich verstehe es auch nicht.......

Datenblatt Controller
Timingdiagramm lesen und verstehen!

E ist der Übernahme-Eingang.
Der ist immer L
Dann Daten und RS und RW passend setzen

DANN E auf H, mindestens ca. 750ns auf H lassen, dann wieder auf L

Während E auf H ist, müssen Daten, RS, RW stabil am Display anliegen.
Dann gibt es noch Haltezeiten vor und nach dem E-Impuls, die sind aber 
bei üblichen AVR-Taktfrequenzen unkritisch.

Außerdem fällt es sehr schwer Deinen Code zu lesen. Schau Dir mal 
einfach an, wie andere es machen. Mache Dinge sind in einer Zeile 
zusammen merklich lesbarer.

Du steuerst das Display im 8-Bit-Mode an. Da kannman das Datenwort doch 
eher in eine OUT-Anweisung zusammenfassen.

Wenn ich ein "A" ans Display schicken will, schicke ich doch auch ein A 
und zerlege es nicht erst in einzelne Bits.

Auch schon hundertmal geschrieben: die 0-Schieberei ist witzlos.

PORTB |= (0 << D0);
PORTB |= (0 << D1);
PORTB |= (1 << D2); // Display On  Wieso hier Font auf 5x10`?
PORTB |= (0 << D3); // 1 Line Mode Warum? Ich denke, Du hast ein 2x16???
PORTB |= (1 << D4);
PORTB |= (1 << D5);
PORTD |= (0 << D6);
PORTD |= (0 << D7);

PORTB = 0x34; // Display On, 1 Zeile

finde ich lesbarer.

Gruß aus Berlin
Michael

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
darf man fragen warum du deine datenleitungen auf PB und PD 
aufsplittest? unkomfortabler geht es wirklich nicht.

du solltest dafür sorgen, dass du erst deine daten anlegst und dann 
executest.

pumpkin

Autor: Johannes A. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michael

Danke!

und @Christian D.

Sorry, aber wenn Du DIESEN Code nicht selber langsam echt krank findest,
wird Dir wohl kaum noch jemand helfen können...

Und Tschüss
Johannes

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.