- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 4 von 4

Thema: LCD initialisieren

  1. #1
    Neuer Benutzer Öfters hier Avatar von Spitfire
    Registriert seit
    09.07.2012
    Ort
    Niederösterreich
    Beiträge
    28

    LCD initialisieren

    Anzeige

    E-Bike
    Hallo zusammen !!!

    Ich bin gerade dabei, AVR-Tutorial bei http://www.mikrocontroller.net/artic...-Tutorial:_LCD durchzuarbeiten. Jetzt ist es endlich soweit ein LCD anzuschließen. Nur ist da leider für einen Anfänger die erklärung recht schwer zu durchblicken. Ich habe im Netz zwar einiges gefunden, was mir aber bei meinem jetzigen Wissen über Assembler, Atmega und co. nicht recht hilfreich war. Ich benutze das Display Blueline Dotmatrix (EA W162B-N3LW) von Reichelt (http://such002.reichelt.de/?SID=13UB...65f;ACTION=446). Im Turtorial steht das
    $3 und ein paar µs warten öfters im das Steuerregister geschrieben werden soll, aber wer, was wo ist das Steuerregister.

    Ich habe es mit den angaben im Datenblatt (dem Display beigelegt, und bei Reichlt als download verfügbar) versucht. Hierbei soll folgendes am Port ausgegeben werden:

    .........RS......RW.....DB7.....DB6........DB5...D B4
    .........0........0........0.........0...........1 ......0...............4-Bit Datenlänge einschalten (noch im 8-Bit Modus)

    RS = PD4
    RW = PD5
    DB7 = PD3
    DB6 = PD2
    DB5 = PD1
    DB4 = PD0

    Mit ldi r16, 0b00000010 soll bei der Ausgabe auf PD1 ein 1 ausgegeben werden. Der Rest sollte mit 0 belegt werden. Mit dem anschließenden out PORTD, r16 sollten die Ausgänge dementsprechend belegt werden.

    Hier noch der gesammte Quelltext:
    Code:
    .include "m8def.inc"
    .include "lcd-routines.c"
    	
    	ldi r16, 0xFF
    	out DDRD,r16						;Im Datenrichtungsregister PORTD als Ausgang deklarieren
    
    	ldi r16, 0b00000010
    	nop									;Dem Diplay Zeit geben um sich selbst zu initialisieren
    	nop
    	nop
    	nop
    	nop
    	nop
    	out PORTD, r16
    
    	nop									;Dem Diplay Zeit geben um sich selbst zu initialisieren
    	nop
    	nop
    	nop
    	nop
    	nop
    
    	ldi r16, 125					;Ab dieser Zeile ist das Programm nur Abgeschrieben
    
    	mov r17,r16						;  Kopie von r16 in r17 eintragen
    
    	swap r16						; vertauscht die beiden Nibbles von r16 (Die Bit´s 0-3 und 4-8 werden vertauscht)
    
    	andi r16, 0b00001111			; Nur die vier unteren (mit 1 markierten)
    									; Bits werden übernommen, alle anderen werden null
    
    	sbr r16, 0b00010000				; Bit 4 setzen, alle anderen Bits bleiben gleich
    	
    	out PORTD, r16
    	
    	sbi PORTD, 5					;Den 5.PORTD (PD5) auf High setzen, um den Display zu Signalisieren, das es die Daten von PD0 bis PD4 übernehmen kann
    	nop								; 3 Taktzyklen warten, um dem Display, für die Datenübernahme, genügend Zeit zu geben
    	nop
    	nop
    	cbi PORTD, 5					;PD5 wieder auf LOW setzen
    
    	andi r17, 0b00001111
    
    	sbr r17, 1<<4					; nur eine andere Schreibweise von oben
    
    	out PORTD, r17
    
    	sbi PORTD, 5
    	nop
    	nop
    	nop
    	cbi PORTD, 5
    Ich hoffe ihr könnt mir ein paar Tip´s zu initialisierung geben, und bitte nicht vergessen, ich stehe noch ganz am Anfang mit dem Assembler-Programmieren.

    Danke für eure bemühungen !!

  2. #2
    Neuer Benutzer Öfters hier Avatar von Spitfire
    Registriert seit
    09.07.2012
    Ort
    Niederösterreich
    Beiträge
    28
    Hallo zusammen !!

    ICh habe natürlich weiter probiert, und den Code nochmal verändert:

    Code:
    	ldi r18, 0b00010100					;Dem Diplay Zeit geben um sich selbst zu initialisieren
    	ldi r16, HIGH(RAMEND)
    	out sph, r16
    	ldi r16, LOW(RAMEND)
    	out SPL, r16
    
    	rcall Warten
    
    .....
    .....
    .....
    
    Warten:
    	dec r18
    	brne Warten
    ret
    Eigentlich hat sich nur die Warteschleife, welche dem Display Zeit gibt um sich selbst zu initilaiseren, geändert. Hat aber nicht wirklich einen Unterschied gemacht.

    Danke nochmals

  3. #3
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Takte der Befehle:

    dec 1
    brne 1/2
    rcall 3
    ret 4

    In der Schleife 19*3 +2 (19 mal springen und einmal nicht springen) +3 +4 ergibt 66. Bei 16MHz-Takt bedeutet das 1Sekunde/16000000*66 oder 0,000004125s oder 4,125µs Verzögerung. Das scheint mir viel zu kurz, vor allem wenn "zähe" Funktionen wie clear oder cursorhome Ausführungszeiten im ms-Bereich haben. Auch den Hinweis rechts auf Seite drei des Datenblatts sollte man beachten. Ich habe mir die Wikiseite noch nicht angeschaut, aber ich vermute, du prüfst das busy nicht. Im Zweifel immer mit deutlich zu großer Verzögerung starten.

    Link zum LCD: http://www.reichelt.de/Hintergrund-b...=0&OFFSET=500&
    Link zum Datenblatt: http://www.reichelt.de/index.html?;A...BL%2523EAS.pdf

    Gruß

    mic

    [Edit]
    Das LCD hat zwei Register. Ins Datenregister schreibt man die Werte, ins Steuerregister die Kommandos. Mit der R/S-Leitung wird zwischen Kommando und Daten unterschieden, ein Low bedeutet, die angelegten Signale an den Datenleitungen werden als Kommando interpretiert, ein High bedeutet, jetzt kommen Daten. Bei einer 4bit-Ansteuerung werden die Datenbytes in zwei Schritten übertragen, wenn ich mich recht erinnere zuerst das High- und dann das Lownipple.

    Die Übernahme der angelegten Datenpegel steuert man mit dem E-Signal, bei einer Flanke nach Low werden die Pegel an den Dateneingängen eingelesen. Die Datenflußrichtung steuert man mit dem R/W-Signal, low bedeutet, ins LCD reinschreiben. Weil die einfachste Ansteuerung eines LCD ohne Auswertung des busy auskommt (und man sich so einen Pin am µC spart) kann man diese Leitung direkt mit GND verbinden.

    Da das LCD natürlich nach dem Einschalten nicht weiß, ob es mit 4 oder 8 Bits angesteuert wird, startet es im 8bit-Modus. Deshalb muss man zu Beginn der Initialisierung zuerst auf 4 Bits umschalten. Das Kommando dazu lautet, formatiert für den 8bit-Modus, so:

    0b0010 0000 (nach dem Beispiel im Datenblatt Seite 4)

    Das bedeutet, diesen ersten Wert für das LCD muss man mit einer 8 Bit Ausgabefunktion senden. Beim Senden muss R/W auf Low für "Schreiben" und RS auf Low für "Kommando" gesetzt werden. Das eigentliche Senden läuft dann so ab:

    E auf 0
    RS auf 0


    setzen und kurz warten, bis sich die Pegel eingestellt haben (tAS)

    E auf 1

    D4-D7 auf das Daten Highnipple

    Wieder warten, bis sich die Pegel eingestellt haben (PWEH)

    E auf 0

    Jetzt hat das LCD die Daten übernommen und führt den Befehl aus. Günstig ist es, wenn man nun noch auf den Datenmodus zurückschaltet:

    RS auf 1

    Nach einer weiteren Wartezeit, bis TCYCE erreicht ist, ist das Senden fertig.

    Ab jetzt erwartet das LCD alle weiteren Daten im 4 Bit-Format, ein Byte wird dann durch das einzelne Senden des High- und des Lownipples übertragen. Da der oben beschriebe Ablauf beim Senden auch ein Lownipple übertragen kann, packen wir es in eine Funktion der wir das auszugebende Nipple als Parameter übergeben:

    send_nipple(nipple)

    und ändern oben nach

    D4-D7 auf das nipple

    und senden die Initialisierung:

    send_nipple(0b0010) 4-Bit Datenlänge einschalten (noch im 8-Bit Modus)

    send_nipple(0b0010) 4-Bit Datenlänge, 1-zeiliges Display, 5x7 Font
    send_nipple(0b0000)

    send_nipple(0b0010) nochmal senden, weil manchmal nötig
    send_nipple(0b0000)

    send_nipple(0b0000) Display ein, Cursor ein, Cursor blinken
    send_nipple(0b1111)

    send_nipple(0b0000) Display löschen, Cursor auf 1. Spalte von 1. Zeile
    send_nipple(0b0001)

    send_nipple(0b0000) Cursor Auto-Increment
    send_nipple(0b0110)

    Jede Leerzeile zwischen den Sende-Aufrufen steht für eine Wartezeit die der Ausführungszeit des jeweils vorangegangenen Befehls entspricht. Für den groben Test würde ich mit 2ms pro Leerzeile anfangen...

    Da send_nipple() nur Kommandos senden kann (RS ist beim Senden immer low) benennen wir es in send_kommando() um und erzeugen eine Kopie in der wir RS auf 0 in RS auf 1 ändern und an deren Ende wir eine kurze Verzögerung für die Darstellung des Zeichens anfügen und die wir anschliesend send_daten() nennen:

    send_daten(114)
    send_daten(103)
    send_daten(104)
    send_daten(55)
    send_daten(124)
    send_daten(145)
    send_daten(163)
    send_daten(164)

    Ich hoffe,das funzt so.
    Geändert von radbruch (03.08.2012 um 19:28 Uhr)
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #4
    Neuer Benutzer Öfters hier Avatar von Spitfire
    Registriert seit
    09.07.2012
    Ort
    Niederösterreich
    Beiträge
    28
    Hallo Radbruch !!

    Das Haut jetzt hin !!

    Danke für deine Hilfe. Am Anfang habe ich mich zwar überhaupt nicht durchgeblickt, aber mit dem Studieren deiner Zeilen, und viel ausprobieren hat es aufeinmal geklappt. Jetzt werde ich nochmal den fertigen Code studieren, warum das so funktioniert. Aber dein Eintrag war eine sehr große Hilfe.

    Danke nochmals

    Spitfire

Ähnliche Themen

  1. String initialisieren ohne 0 ?
    Von Siro im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 18.03.2011, 18:45
  2. structs initialisieren
    Von Siro im Forum C - Programmierung (GCC u.a.)
    Antworten: 12
    Letzter Beitrag: 18.02.2011, 09:53
  3. Display Initialisieren HILFE
    Von Juney im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 28.10.2010, 13:15
  4. Adc initialisieren beim Atmega 16
    Von Destrono im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 25.05.2010, 13:16
  5. LCD - initialisieren im 4-Bit Modus
    Von henne im Forum AVR Hardwarethemen
    Antworten: 2
    Letzter Beitrag: 12.03.2005, 01:26

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen