Forum: Mikrocontroller und Digitale Elektronik LCD EA DIP204-4 Initialisieren


von Jochen A. (neurotoxer)


Angehängte Dateien:

Lesenswert?

Guten Abend,
da ich dieses Forum häufig nutze wenn ich Fragen zur uC Programmierung 
habe, dachte ich es ist an der Zeit auch mal etwas zurückzugeben...
Also stelle ich jetzt mal meine LCDroutinen vor.

Hintergrund:
Das LCD Display EA DIP204-4 hat mir leichte Kopfschmerzen bereitet.
Ich habe schon diverse andere LCDs zum laufen gebracht, aber bei diesem 
hatte ich Schwierigkeiten mit der Initialisierung. Da offenbar auch 
andere Nutzer dieses Forums schon Probleme mit diesem LCD hatten, poste 
ich mal meine Lösung zum Init.
Das Display verwendet den Controller KS0073. Dieser ist zwar nahezu 100% 
HD44780 kompatibel(laut Datenblatt), aber auch nur nahezu...
Denn die Initialisierung läuft anders ab als beim HD44780. Hierzu eine 
Passage aus den Datenblatt es KS0073:
  1) Clear Display
  2) Set Functions instruction
  3) Control Display ON/OFF instruction
  4) Set Entry Mode instruction
  5) Set Extension Function instruction
  6) Enable Scroll/Shift instruction
  7) Set scroll Quantity instruction
danach muss unter umständen wieder Clear Display ausgeführt werden.

Die passenden Kommandos für eine 4x20 Zeichen initialisierung bitte dem 
Dateianhang entnehmen.

mfg Neurotoxer

von Marcel N. (rufnag)


Lesenswert?

sers,
hat vielleicht die initialisierung jemand auch für assembler???
gru?

von Marcel N. (rufnag)


Lesenswert?

hab ein ea dip204-4 mit ks0073 kontroller
Hier mein code: (Leider funktioniert er nicht, alles wie im tutorial, 
nur init anders:)
.include "m8def.inc"

.def temp1 = r16
.def temp2 = r17
.def temp3 = r18


           ldi temp1, LOW(RAMEND)      ; LOW-Byte der obersten 
RAM-Adresse
           out SPL, temp1
           ldi temp1, HIGH(RAMEND)     ; HIGH-Byte der obersten 
RAM-Adresse
           out SPH, temp1

           ldi temp1, 0xFF    ; Port D = Ausgang
           out DDRD, temp1

           rcall lcd_init     ; Display initialisieren
           rcall lcd_clear    ; Display löschen

           ldi temp1, 'T'     ; Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 'e'     ; Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 's'     ; Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 't'     ; Zeichen anzeigen
           rcall lcd_data

loop:
           rjmp loop

;.include "lcd-routines.asm"            ; LCD-Routinen werden hier 
eingefügt

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                 LCD-Routinen                ;;
;;                 ============                ;;
;;              (c)andreas-s@web.de            ;;
;;                                             ;;
;; 4bit-Interface                              ;;
;; DB4-DB7:       PD0-PD3                      ;;
;; RS:            PD4                          ;;
;; E:             PD5                          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



 ;sendet ein Datenbyte an das LCD
lcd_data:
           mov temp2, temp1             ; "Sicherungskopie" für
                                        ; die Übertragung des 2.Nibbles
           swap temp1                   ; Vertauschen
           andi temp1, 0b00001111       ; oberes Nibble auf Null setzen
           sbr temp1, 1<<4              ; entspricht 0b00010000
           out PORTD, temp1             ; ausgeben
           rcall lcd_enable             ; Enable-Routine aufrufen
                                        ; 2. Nibble, kein swap da es 
schon
                                        ; an der richtigen stelle ist
           andi temp2, 0b00001111       ; obere Hälfte auf Null setzen
           sbr temp2, 1<<4              ; entspricht 0b00010000
           out PORTD, temp2             ; ausgeben
           rcall lcd_enable             ; Enable-Routine aufrufen
           rcall delay50us              ; Delay-Routine aufrufen
           ret                          ; zurück zum Hauptprogramm

 ; sendet einen Befehl an das LCD
lcd_command:                            ; wie lcd_data, nur RS=0
           mov temp2, temp1
           swap temp1
           andi temp1, 0b00001111
           out PORTD, temp1
           rcall lcd_enable
           andi temp2, 0b00001111
           out PORTD, temp2
           rcall lcd_enable
           rcall delay50us
           ret

 ; erzeugt den Enable-Puls
 ;
 ; Bei höherem Takt (>= 8 MHz) kann es notwendig sein,
 ; vor dem Enable High 1-2 Wartetakte (nop) einzufügen.
 ; Siehe dazu Beitrag "Re: Bitte helft mir. Schon wieder AtMega16"
lcd_enable:
           sbi PORTD, 5                 ; Enable high
           nop                          ; 3 Taktzyklen warten
           nop
           nop
           cbi PORTD, 5                 ; Enable wieder low
           ret                          ; Und wieder zurück

 ; Pause nach jeder Übertragung
delay50us:                              ; 50us Pause
           ldi  temp1, $42
delay50us_:dec  temp1
           brne delay50us_
           ret                          ; wieder zurück

 ; Längere Pause für manche Befehle
delay5ms:                               ; 5ms Pause
           ldi  temp1, $21
WGLOOP0:   ldi  temp2, $C9
WGLOOP1:   dec  temp2
           brne WGLOOP1
           dec  temp1
           brne WGLOOP0
           ret                          ; wieder zurück

 ; Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
lcd_init:
           ldi  temp3,50
powerupwait:
           rcall  delay5ms
           dec  temp3
           brne powerupwait
           ldi temp1, 0b00100100        ;
           out PORTD, temp1             ;
           rcall lcd_enable             ;
           rcall delay5ms

           ldi temp1, 0b00001001        ; 4bit-Modus einstellen
           out PORTD, temp1
           rcall lcd_enable
           rcall delay5ms
           ldi temp1, 0b00100000        ; 4Bit
           rcall lcd_command
           ldi temp1, 0b00001100        ; Display ein  Cursor aus  
kein Blinken
           rcall lcd_command
           ldi temp1, 0b00000110        ; inkrement / kein Scrollen
           rcall lcd_command
           ret

 ; Sendet den Befehl zur Löschung des Displays
lcd_clear:
           ldi temp1, 0b00000001   ; Display löschen
           rcall lcd_command
           rcall delay5ms
           ret

 ; Sendet den Befehl: Cursor Home
lcd_home:
           ldi temp1, 0b00000010   ; Cursor Home
           rcall lcd_command
           rcall delay5ms
           ret
bitte um hilfe

von Jochen A. (neurotoxer)


Lesenswert?

Servus,
versuchs mal mit dieser Init-Routine:

lcd_init:
           ldi  temp3,50
powerupwait:
           rcall  delay5ms
           dec  temp3
           brne powerupwait

           rcall lcd_clear
           ldi temp1, 0b00100100
           rcall lcd_command
           ldi temp1, 0b00001100
           rcall lcd_command
           ldi temp1, 0b00100000
           rcall lcd_command
           ldi temp1, 0b00000110
           rcall lcd_command
           ldi temp1, 0b00100100
           rcall lcd_command
           ldi temp1, 0b00001001
           rcall lcd_command
           ldi temp1, 0b00100000
           rcall lcd_command
           rcall lcd_clear

           ret

Auf die Reihenfolge der Kommandos achten! Sonst streikt das Display.

mfg Neurotoxer

von Marcel N. (rufnag)


Lesenswert?

super,
danke. werde es testen und hoffentlich mal was auf meinem display sehen

von Alfred Q. (higedigdag)


Lesenswert?

@Jochen

Ich habe deine Lib oben benutzt. Leider klappt es bei mir trotzdem nicht 
:(
Das Display zeigt mir nur alle Felder als weiße Kästchen an.

Kann es zu Problemen führen wenn man die Leitungen zu lang hat? Hab ca. 
40cm Kabel bis zum LCD.

mfg andy

von µluxx .. (uluxx) Benutzerseite


Lesenswert?

Codesammlung ?

von Rudolph (Gast)


Lesenswert?

Alle Felder als weisse Kästchen?
Kontrast-Spannung?

von Matthias (Gast)


Lesenswert?

> Das Display zeigt mir nur alle Felder als weiße Kästchen an.

Standardfrage: Weiße Kästen kommen beim DIP-204 auch wenn die 
Kontrastspannung nicht stimmt, schon mal geprüft?

von Matthias (Gast)


Lesenswert?

Deine Initialisierung für 4-Bit ist nicht korrekt:
Nimm mal diese:
1
 display_command(0x24);
2
 display_command(0x09);
3
 display_command(0x20);
4
 display_command(0x0C);
5
 display_command(0x01);
6
 display_command(0x06);

Damit läuft Dein Programm bei mir mit Anpassung auf einen 8051er und 
DIP204-4.

von Alfred Q. (higedigdag)


Lesenswert?

Hab meinen Fehler gefunden :)

Ich hatte den RES(reset) auf LOW gelegt.

Jetzt klappts wunderbar, auch mit der Routine von Peter Fleury.

Andy

http://i207.photobucket.com/albums/bb49/higedigdag/IMG_2521.jpg

von Marcel N. (rufnag)


Lesenswert?

sers,
das mit dem reset ist so ne sache, im datenblatt steht doch bei reset L.
warum muss das dann auf high liegen wenn es gehen soll??

von Alfred Q. (higedigdag)


Lesenswert?

ja das versteh ich auch nicht...
aber ich glaub es ist eher so, dass es nur auf low gelegt wird wenn der 
reset gemacht werden soll.
ich hab ihn jetzt einfach nicht angeschlossen(auch nicht auf high 
gelegt) weil im datenblatt bei mir steht L und nicht L/H also geh ich 
davon aus das man es nicht auf high legen muss...

es klappt ja jetzt super :)

mfg andy

von Marcel N. (rufnag)


Lesenswert?

kannst du mal deine routine posten, die weißen kästchen stehen bei mir 
wie ne eins, langsam weiß ich nicht mehr was ich ncoh machen kann

von Alfred Q. (higedigdag)


Lesenswert?

also ich habe diese genommen:

http://homepage.hispeed.ch/peterfleury/avr-software.html#libs

du musst in der lcd.h nur den controller umstellen auf den KS0073 und 
dann deine ports und so anpassen.

dann sollte es gehen

von Marcel N. (rufnag)


Lesenswert?

endlich, vielen dank an alle, es war letztendlich auch nur der 
resetanschluss, oh man, obwohl es im datenblatt so steht
jetzt kann ich endlich mal anfangen mit dem lcd zu spielen

von Jochen A. (neurotoxer)


Angehängte Dateien:

Lesenswert?

Servus.
Da es eine Nachfrage wegen der Pinbelegung des Displays gab, habe ich 
diese mal als pdf angehängt.

von Thomas M. (thomas1123) Benutzerseite


Lesenswert?

Ich bin irgentwie am verzweifeln

wenn ich das display mit einem pic16f690 initialisiere dann klappt alles 
wunderbar aber wenn ich die gleiche routine benutze um es mit einem 
16F887 zu initialisieren geht fast nix ausser das alle segmente schwarz 
werden. wenn das display bei der init eingeschaltet wird.

was könnte das sein?
ich habe es schon nen halbes dutzend mal auf meinem steckbrett aufgebaut 
und auch bestimmt 100 mal die belegung nachgeschaut aber es will einfach 
nicht wie gesagt mit dem 16f690 kein problem.

von holger (Gast)


Lesenswert?

ADCON auf digital IO umgeschaltet ?
Ansonsten kann man ohne Code und/oder Schaltung
nicht viel sagen.

von Thomas M. (thomas1123) Benutzerseite


Lesenswert?

ja ANSEL und ANSELH sind beider auf 0 gesetzt.

zur schaltung
Steckbrett mit 5V Festspannungsregler
dann das Display "normal" angeschlossen PORTC sind die 8 Datenleitungen 
und auf PORTA habe ich die 3 Steuerleitungen. also nichts spektakuläres 
habe sowas schon nen paar dutzend mal auf nem Steckbrett aufgebaut und 
es funktionierte alles bestens sogar mit 8MHz INTOSC beim PIC16F690. Ich 
habe inzwichen sogar beim 16F887 den LFINTOSC mit 32khz genommen und die 
Ausgänge überprüft und ja die tun wie se sollen. bin langsam ratlos habe 
mir sogar schonmal angeschaut wie das bei dme controller mit spi abläuft 
und festgestellt um 1Byte daten an das ding zu senden muss man 3 byte 
über den bus schieben und das bei maximal 50kHz SPI CLK

von Alain F. (fox82)


Lesenswert?

Was für viele selbstverständlich ist, war für mich zuerst nicht ganz 
klar.
Habe alles so angeschlossen wie im dislplay.h beschrieben. Die Pins für 
den 4Bit-Modus werden vom DIP204 Pin 11 bis 14 benötigt.

Durch andere Beiträge, habe ich auch gesehen, dass jemand vergessen hat 
R/W (SID) auf GND zu schalten. Habe dies gemacht und es funktioniert 
wunderbar!!!

Danke für das Hinaufstellen der Initialisierung.

Gruss Alain

von Patrick E. (f4550tim)


Lesenswert?

Hey, also ich habe einen PIC18F4550.

Habe folgenden Code:
1
#include "display.h"
2
#include <p18f4550.h>    // Pic .h eigebunden
3
4
#pragma config FOSC = HS  //Oscilator Art zwischen 4MHz - 20MHz
5
#pragma config PWRT = ON  // AN
6
#pragma config BOR = OFF
7
#pragma config WDT = OFF  // Watch Dog AUS
8
#pragma config LVP = OFF
9
#pragma config PBADEN = OFF
10
#pragma config VREGEN = OFF
11
#pragma config MCLRE = ON  // Master Reset AN
12
13
#pragma code     //Code soll in den Programmspeicher geschrieben werden
14
15
16
int main(void){
17
  DDRC=0b00000001;    //led an PC0
18
  display_init();
19
  display_ptext("Display-Routinen",1,2);
20
  display_ptext("Version: 0.2",2,4);
21
  display_ptext("Author: NeuroToxer",3,1);
22
  display_ptext("Date: 27.09.2007",4,2);
23
  //Endlosschleife
24
  while(1!=2);
25
  return 1;
26
}

Ich habe die AVR include oben rausgeschmissen, weil ich nen PIC habe. 
Habe alles nach Bild angeschlossen. Beim Compilen bekomme ich folgenden 
Fehler:

C:\MCC18\h\display.h:52:Error: syntax error

Ich habe deine display.h in den normalen .h Ordner gezogen, und von da 
meint er einen Fehler in der Zeile 53. Das ist da wo
asm volatile("nop");
beginnt. Hat das was damit zu tun weil ich einen PIC habe ? Und was muss 
ich umschreiben ? Oder habe ich etwas einfaches übersehen ?

lg Tim

von Thomas P. (tomson68)


Lesenswert?

Hier noch eine funktionierende Version einer Initialisierung für das LCD 
EA DIP204-4 (NLED), welches an PORTB (=LCD_PORT) angeschlossen ist. PB0 
bis PB5:  D4, D5, D6, D7, RS, E. R/W auf Masse! RES offen!

µC: ATmega 8L, 8MHz

Im 4 Zeilen Modus können die Zeilen mit der entsprechenden Adresse 
angesprochen werden.

Die wait-Warteschleifen funktionieren für 8MHz-Taktfrequenz und müssen 
evtl. bei anderen Frequeunzen angepasst werden. Bitte ausprobieren!

Gruß
Thomas

;########################################
LCD_INITIALISIERUNG_KS0073:

  rcall wait_100ms ;Warteschleife 100ms, nur wenn nötig

  ldi  temp,0b00000011  ;muss 3mal hintereinander gesendet
  out  PORTB,temp    ;werden zur Initialisierung
  rcall  lcd_enable  ;1x
  rcall  wait5ms
  rcall  lcd_enable  ;2x
  rcall  wait5ms
  rcall  lcd_enable  ;und 3x!
  rcall  wait5ms

  ldi  temp,0b00000010  ;4bit-Modus einstellen
  out  PORTB,temp
  rcall  lcd_enable
  rcall  wait5ms

  ldi  temp,0b00100100 ;4-bit RE=1
  rcall  lcd_command

  ldi  temp,0b00001001 ; 4 Zeilen-Modus
  rcall  lcd_command

  ldi  temp,0b00100000 ; 4-bit RE=0
  rcall  lcd_command

  ldi  temp,0b00001100 ;Display ON, Cursor OFF
  rcall  lcd_command

  ldi  temp,0b00000001  ; LCD_CLEAR
  rcall  lcd_command

  ldi  temp,0b00000110 ;Cursor Auto-Inc
  rcall  lcd_command

ret
;############################################
;############################################
LCD_ENABLE:
  sbi  PORTB,LCD_E  ; Enable high
  rcall  wait50us  ; kurze PAUSE
  cbi  PORTB,LCD_E  ; Enable low
  rcall  wait50us  ; kurze PAUSE

ret
;############################################
;############################################
; CURSOR Sprung in ZEILE!
LCD_ZEILE1:

  ldi  temp,0b00000010  ;Cursor at home
  rcall  lcd_command
ret
;#############################################
; CURSOR Sprung in ZEILE2
LCD_ZEILE2:

  ldi  temp,0b10100000
  rcall  lcd_command
ret
;#############################################
; CURSOR Sprung in ZEILE3
LCD_ZEILE3:

  ldi  temp,0b11000000
  rcall  lcd_command
ret
;#############################################
; CURSOR Sprung in ZEILE4
LCD_ZEILE4:

  ldi  temp,0b11100000
  rcall  lcd_command
ret

;#############################################
;#############################################
; sendet ein Datenbyte an das LCD
; INPUT: temp
; rcall LCD_DATA      ; DATENBYTE an LCD inp: temp
;
LCD_DATA:

  push  temp  ; "Sicherungskopie"
  push  temp  ; "Sicherungskopie"
  swap  temp  ; Vertauschen
  andi  temp,0b00001111  ; oberes Nibble auf Null setzen
  out  LCD_PORT,temp  ; ausgeben

  sbi  LCD_PORT,LCD_RS  ; RS ein (high)
  rcall  lcd_enable  ; Enable-Routine aufrufen

  pop  temp  ; Kopie wieder laden
  andi  temp,0b00001111  ; oberes Nibble auf Null setzen
  out  LCD_PORT,temp  ; ausgeben

  sbi  LCD_PORT,LCD_RS  ; RS ein  (high)
  rcall  lcd_enable  ; Enable-Routine aufrufen
  pop  temp  ; Kopie wieder laden
ret
;#############################################
;sendet einen Befehl an das LCD;wie lcd_data, nur ohne RS zu setzen
; INPUT: temp

LCD_COMMAND:
  push  temp  ; "Sicherungskopie"
  swap  temp  ; Vertauschen
  andi  temp,0b00001111  ; oberes Nibble auf Null setzen
  out  LCD_PORT,temp  ; ausgeben

  cbi  LCD_PORT,LCD_RS  ; RS aus (low)
  rcall  lcd_enable  ; Enable-Routine aufrufen

  pop  temp  ; Kopie wieder laden
  andi  temp,0b00001111  ; oberes Nibble auf Null setzen
  out  LCD_PORT,temp  ; ausgeben

  cbi  LCD_PORT,LCD_RS  ; RS aus (low)
  rcall  lcd_enable  ; Enable-Routine aufrufen
  rcall  wait5ms  ; Pause (wichtig)
ret
;#############################################
;#############################################
;5ms Pause   (Werte anpassen an CPU-Takt)
wait5ms:
  push  temp1  ; temp1 auf dem Stack sichern
  push  temp2  ; temp2 auf dem Stack sichern
;------------
  ldi  temp1,50
  clr  temp2

wait5ms_:
  dec  temp2
  brne  wait5ms_
  dec  temp1
  brne  wait5ms_
;------------
  pop  temp2  ; temp2 wiederherstellen
  pop  temp1  ; temp1 wiederherstellen
ret
;#############################################
;#############################################
;Pause nach jeder Übertragung;50us Pause
;(Werte anpassen an CPU-Takt)

wait50us:
  push  temp  ; temp auf dem Stack sichern
  ldi  temp,130
wait50us_:
  dec  temp
  brne  wait50us_
  pop  temp  ; temp wiederherstellen
ret

von markus (Gast)


Lesenswert?

hallo zusammen!

wie muss der reset pin jetzt beschalten sein?
es handelt sich um den 4bit modus und ich bekomme nichts raus.
controller ist ein LPC

von tomson68 (Gast)


Lesenswert?

Der Reset-Pin bleibt unbeschaltet, offen!

Gruß
Thomas

von NurEinGast (Gast)


Lesenswert?

Hallo zusammen,
Ich habe vor längerer Zeit das Ea-Dip204-4 seriell angeschlossen.
Das bedeutet, dass es etwas langsamer geht, dafür braucht man aber nur 2 
Leitungen.
Kann ja manchmal auch ganz hilfreich sein.
Wenn's interessiert, genaueres findet ihr hier. Ich hatte das damals als 
Treiber für das Ethernut Board implementiert. Aber das eigentlich 
Interessante kann jeder dort auch für andere Umgebungen herauslesen

http://www.tklinux.de/ks0073.html

von A. R. (and)


Angehängte Dateien:

Lesenswert?

Hallo,
auch wenn dieser Thread schon älter ist:

Ich bin gerade dabei das LCD Modul "EA DIP203B-4NLW" ans laufen zu 
bekommen.
Zur Hardware: Ich verwende den Atmega2560. Im Anhang die Pinbeleung.

Scheinbar gibt es Probleme mit der Initalisierung.
Es leuchten einfach irgnedwelche Zeichen.

Habe ein kleines Testprogramm. Die Funktion "display_clear();" scheint 
aufjedenfall mal zu funktionieren.



Vielen Dank schonmal vorab für eure Hilfe.




Hauptprogramm:
1
#define F_CPU 14745600UL     // CPU Taktfrequenz
2
#include <util/delay.h>       // Für Wartezeiten: _delay_ms();
3
#include <avr/io.h>
4
#include <inttypes.h>
5
#include <stdlib.h>
6
#include <string.h>
7
#include <stdio.h>
8
#include <avr/pgmspace.h>
9
#include "display.h"
10
#include "define.h"
11
12
13
14
int main(void){
15
16
    // ------------------------------------------------------------
17
    // Initalisierung
18
    // ------------------------------------------------------------      
19
    DDRC  = 0xFF;                   // Digitale Ausgänge
20
      DDRD  = 0xFF;
21
          
22
    PORTD |= (1 << PD7);          // Setzte R/W_NOT  // DIR = 1
23
    PORTD &= ~(1 << PD5);          // R/W = 0
24
    
25
    _delay_ms(2000);
26
      
27
    //++++++++++++++++++ TEST  ++++++++++++++++++//
28
    PORTC |= (1<<PC0);      // Bit setzen
29
    PORTC |= (1<<PC1);      // Bit setzen
30
    PORTC |= (1<<PC2);      // Bit setzen
31
    _delay_ms(500);         // warten
32
    PORTC &= ~(1<<PC0);     // Bit loeschen
33
    PORTC &= ~(1<<PC1);     // Bit loeschen
34
    PORTC &= ~(1<<PC2);     // Bit loeschen
35
    //++++++++++++++++++ TEST  ++++++++++++++++++//  
36
          
37
    display_init();
38
39
40
    // ------------------------------------------------------------
41
    // Hauptprogramm
42
    // ------------------------------------------------------------
43
44
    while(1){
45
      
46
      //++++++++++++++++++ TEST  ++++++++++++++++++//
47
      PORTC |= (1<<PC1);      // Bit setzen
48
      _delay_ms(100);         // warten
49
      PORTC &= ~(1<<PC1);     // Bit loeschen
50
      //++++++++++++++++++ TEST  ++++++++++++++++++//
51
      
52
      PORTD |= (1 << PD7);          // Setzte R/W_NOT  // DIR = 1
53
      PORTD &= ~(1 << PD5);          // R/W = 0
54
            
55
      // ------------------------------------------------------------
56
      // Schreibe Text
57
      // ------------------------------------------------------------
58
      display_clear();
59
      
60
      //++++++++++++++++++ TEST  ++++++++++++++++++//
61
      PORTC |= (1<<PC2);      // Bit setzen
62
      _delay_ms(500);        // warten
63
      PORTC &= ~(1<<PC2);     // Bit loeschen
64
      //++++++++++++++++++ TEST  ++++++++++++++++++//
65
      
66
      _delay_ms(500);
67
      display_ptext("Zeile 1",1,1);
68
      _delay_ms(500);
69
      display_ptext("Test",2,1);
70
      _delay_ms(500);
71
      display_ptext("Zeile 3",3,1);
72
      _delay_ms(500);
73
      display_ptext("123456",4,1);
74
      _delay_ms(3000);
75
76
    }
77
}



Display.h
1
//-----------------------------------------------------------------//
2
//                    KS0073 Display Routinen                      //
3
//-----------------------------------------------------------------//
4
//                       Author: Neurotoxer                        //
5
//                         Date: 27.09.2007                        //
6
//                      Version: 0.2                               //
7
//                          LCD: EA DIP204-4                       //
8
//-----------------------------------------------------------------//
9
10
//-----------------------------------------------------------------//
11
//    Port und Pin Settings
12
//-----------------------------------------------------------------//
13
#define LCD_DATAPORT    PORTD  //Port für die 4 Datenleitungen
14
#define LCD_DATAPORTDR    DDRD
15
#define LCD_DATA0      0
16
#define LCD_DATA1      1
17
#define LCD_DATA2      2
18
#define LCD_DATA3      3
19
#define LCD_SETPORT      PORTD  //Port für die 3 Steuerleitungen
20
#define LCD_SETPORTDR    DDRD
21
#define LCD_RS        6    //Umschalten zwischen Befehl(Low) und Daten
22
#define LCD_E        4    //Enable bei fallender Flanke
23
24
//-----------------------------------------------------------------//
25
//    Display Befehle
26
//-----------------------------------------------------------------//
27
#define LCD_CLEAR      0b00000001    //Löschen des Display, Cursor auf Home
28
#define LCD_FUNCTION    0b00100100    //4-Bitmodus, RE=1
29
#define LCD_FUNCTION2    0b00100000    //4-Bitmodus, RE=0
30
#define LCD_CONTROL      0b00001100    //Display ON, Cursor OFF, Blinken OFF
31
#define LCD_CONTROL2    0b00001101    //Display ON, Cursor OFF, Blinken ON
32
#define LCD_CONTROL3    0b00001110    //Display ON, Cursor ON, Blinken OFF
33
#define LCD_CONTROL4    0b00001111    //Display ON, Cursor ON, Blinken ON
34
#define LCD_EXTENDED    0b00001001    //5-Dot Fontwidth, Normal Cursor, 4 Lines
35
#define LCD_ENTRYMODE    0b00000110    //Segment Bidirectional Function (Seg1->Seg60)
36
#define LCD_DDRAM      0b10000000    //DDRAM Adresse setzen
37
38
//-----------------------------------------------------------------//
39
//    Zeilenadressen und Länge einer Zeile
40
//-----------------------------------------------------------------//
41
#define LCD_LINE1      0x00
42
#define LCD_LINE2      0x20
43
#define LCD_LINE3      0x40
44
#define LCD_LINE4      0x60
45
int   LCD_LINELENGTH=    20;
46
int   LCD_LINES=      4;
47
48
// xus Pause
49
void pause_us(int us){
50
  int y=us;
51
  while(y>0){
52
    asm volatile("nop");
53
    asm volatile("nop");
54
    asm volatile("nop");
55
    asm volatile("nop");
56
    asm volatile("nop");
57
    asm volatile("nop");
58
    y--;
59
  }
60
}
61
62
//Display Enable
63
void display_enable(void){
64
  LCD_SETPORT&=~(1<<LCD_E);        //RS Low
65
  LCD_SETPORT|=(1<<LCD_E);        //RS High
66
  asm volatile("nop");
67
  LCD_SETPORT&=~(1<<LCD_E);        //RS Low
68
}
69
70
//Byte senden
71
void display_send(uint8_t byte){
72
  LCD_DATAPORT=(byte&0b11110000);      //1. High Nibble senden
73
  display_enable();
74
  LCD_DATAPORT=(byte<<4);        //2. Low Nibble senden
75
  display_enable();
76
  pause_us(100);
77
}
78
79
//Datenbyte senden
80
void display_data(uint8_t byte){
81
  LCD_SETPORT|=(1<<LCD_RS);        //RS High
82
  display_send(byte);
83
}
84
85
//Befehlsbyte senden
86
void display_command(uint8_t byte){
87
  LCD_SETPORT&=~(1<<LCD_RS);        //RS Low
88
  display_send(byte);
89
  pause_us(2000);
90
}
91
92
//Display löschen, Cursor auf Home
93
int display_clear(void){
94
  display_command(LCD_CLEAR);
95
  return 1;
96
}
97
98
//Text ausgeben
99
int display_text(char *text){
100
  int z=0;
101
  while(text[z]!='\0'){
102
    display_data(text[z]);
103
    z++;
104
  }
105
  return 1;
106
}
107
108
//Cursor positionieren
109
int display_position(int z, int s){
110
  if(z>LCD_LINES || s>LCD_LINELENGTH)
111
    return 0;
112
  uint8_t addr=LCD_LINE1;
113
  if(z==2)
114
    addr=LCD_LINE2;
115
  if(z==3)
116
    addr=LCD_LINE3;
117
  if(z==4)
118
    addr=LCD_LINE4;
119
  addr+=s;
120
  addr|=LCD_DDRAM;
121
  display_command(addr);
122
  return 1;
123
}
124
125
//Text an Position ausgeben
126
int display_ptext(char *text, int zeile, int spalte){
127
  display_position(zeile, spalte);
128
  display_text(text);
129
  return 1;
130
}
131
132
133
//Display initialisieren
134
//Der KS0073 möchte so initialisiert werden:
135
//1) Clear Display
136
//2) Set Functions instruction
137
//3) Control Display ON/OFF instruction
138
//4) Set Entry Mode instruction
139
//5) Set Extension Function instruction
140
//6) Enable Scroll/Shift instruction
141
//7) Set scroll Quantity instruction
142
//8) Clear Display
143
144
int display_init(void){
145
  pause_us(40000);
146
  
147
  
148
  LCD_DATAPORTDR|=(1<<LCD_DATA0);    //Pins als Ausgänge konfigurieren
149
  LCD_DATAPORTDR|=(1<<LCD_DATA1);
150
  LCD_DATAPORTDR|=(1<<LCD_DATA2);
151
  LCD_DATAPORTDR|=(1<<LCD_DATA3);
152
  LCD_SETPORTDR|=(1<<LCD_RS);
153
  LCD_SETPORTDR|=(1<<LCD_E);
154
  
155
  
156
  display_command(0x24);
157
  display_command(0x09);
158
  display_command(0x20);
159
  display_command(0x0C);
160
  display_command(0x01);
161
  display_command(0x06);
162
        
163
  display_command(LCD_CLEAR);      //1
164
  display_command(LCD_FUNCTION);    //2
165
  display_command(LCD_CONTROL);    //3
166
  display_command(LCD_FUNCTION2);
167
  display_command(LCD_ENTRYMODE);    //4
168
  display_command(LCD_FUNCTION);
169
  display_command(LCD_EXTENDED);    //5
170
  display_command(LCD_FUNCTION2);
171
  display_command(LCD_CLEAR);      //8
172
  
173
  return 1;
174
}

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.