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
sers, hat vielleicht die initialisierung jemand auch für assembler??? gru?
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
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
super, danke. werde es testen und hoffentlich mal was auf meinem display sehen
@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
> 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?
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.
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
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??
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
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
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
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
Servus. Da es eine Nachfrage wegen der Pinbelegung des Displays gab, habe ich diese mal als pdf angehängt.
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.
ADCON auf digital IO umgeschaltet ? Ansonsten kann man ohne Code und/oder Schaltung nicht viel sagen.
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
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
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
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.