PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATMEL AT89s8252 und 16x2 LCD HD 44780 comp.



Monaco
28.04.2005, 13:27
Hi Folgendes ich habe ein Programm für meinen MC und mein Display geschrieben jedoch bekomme ich das LCD nicht initialisiert vieleicht kann mir jemand von euch helfen.
Pin1 GND
Pin2 VCC
Pin3 V0
Pin4 P1.0
Pin5 GND
Pin6 P1.1
Pin7 --
Pin8 --
Pin9 --
Pin10 --
Pin11 P1.2
Pin12 P1.3
Pin13 P1.4
Pin14 P1.5
Pin15
Pin16

So habe ich die Beiden Teile miteinander Verbunden

und mein Assembler Programm
; Autor : Zunker
; Projekt : LCD
; Datum : Thu Apr 28 13:59:12 UTC+0200 2005
; Quarz : 12.288 MHz
;---------------------------------------------------------------

; Konstanten-, Speicher- und Portbelegung
;---------------------------------------------------------------
LCD_RAM CODE 0Ah

LCD_RS EQU P1.0
LCD_RW EQU P1.1
LCD_ENABLE EQU P3.7
LCD_D4 EQU P1.2
LCD_D5 EQU P1.3
LCD_D6 EQU P1.4
LCD_D7 EQU P1.5

; Programmbeginn
;---------------------------------------------------------------
ORG 0000h
jmp start

; Interruptroutinen
;---------------------------------------------------------------

; Funktionen
;---------------------------------------------------------------

; LC-Display Ansteuerung

; LCD initialisieren
LCD_init:

; warten, bis sich das Display initialisiert hat
mov a,#50
LCD_init_sleepsometime:
call LCD_ws
djnz Acc,LCD_init_sleepsometime

; Steuercodes senden
clr LCD_RS
clr LCD_RW
clr LCD_ENABLE
mov a,#00101000b
call LCD_send_b
setb LCD_ENABLE
clr LCD_ENABLE
mov a,#00101000b
call LCD_send_b
mov a,#1100b
call LCD_send_b
call LCD_clear

ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LCD_returnhome:
push ACC
mov a,#128
call LCD_send_b
mov LCD_RAM,#0
pop ACC
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LCD_clear:
push ACC
mov a,#1
call LCD_send_b
mov LCD_RAM,#0
pop ACC
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LCD_printc:
; Ausgabe eines Charakters aus ACC
inc LCD_RAM

push ACC ; bei Überlauf der Spalten in
mov a,LCD_RAM ; nächste Zeile weitersetzen
cjne a,#17,LCD_no_change
mov a,#168
call LCD_send_b
LCD_no_change:
pop ACC
; Zeichen ausgeben
call LCD_send_d
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LCD_prints:
; Ausgabe eines mit 0 terminierten Strings aus DPTR
push ACC
LCD_prints_anf:
clr a
movc a,@A+DPTR
jz LCD_prints_weiter
inc DPTR
call LCD_printc
jmp LCD_prints_anf
LCD_prints_weiter:
pop ACC
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LCD_send_b:
;sendet Befehle aus ACC an Datenport des LCD (interne Funktion)
clr LCD_RS
clr LCD_RW
jmp LCD_send
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;sendet Daten aus ACC an Datenport des LCD (interne Funktion)
LCD_send_d:
clr LCD_RW
setb LCD_RS
LCD_send:
mov c,ACC.7 ; high-nibble ausgeben
mov LCD_D7,c
mov c,ACC.6
mov LCD_D6,c
mov c,ACC.5
mov LCD_D5,c
mov c,ACC.4
mov LCD_D4,c

setb LCD_ENABLE
call LCD_ws
clr LCD_ENABLE

mov c,ACC.3 ; low-nibble ausgeben
mov LCD_D7,c
mov c,ACC.2
mov LCD_D6,c
mov c,ACC.1
mov LCD_D5,c
mov c,ACC.0
mov LCD_D4,c

setb LCD_ENABLE
call LCD_ws
clr LCD_ENABLE

ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Warteschleife für das LC-Display: 1.64ms
; Anzahl Maschinenzyklen: 1679.36
LCD_ws:
push psw
push 0
mov 0,#185
LCD_ws_labelA:
nop
nop
nop
nop
nop
nop
nop
djnz 0,LCD_ws_labelA
nop
pop 0
pop psw
ret
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LCD_msg: db "LCD Ok.",0
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

; Initialisierung
;---------------------------------------------------------------
start:

; die SFR's initialisieren
mov SP, #20h

; LC-Display initialisieren
call LCD_init

mov DPTR,#LCD_msg
call LCD_prints

; Hauptprogramm
;---------------------------------------------------------------
main:
; [...]

; Programmende
;---------------------------------------------------------------
ende:
jmp ende
END

Vieleicht kann einer von euch nen Fehler finden. Wäre nett wenn ihr mich auf mögliche Fehkler hinweisst.

MFG
Zunker

Sandro
28.04.2005, 13:52
Ok, habs noch nicht komplett analysiert.

Aber die erste Zeile die mir auffällt ist die:
LCD_RAM CODE 0Ah
Mein Assembler versteht das garnicht. Gibst du damit nicht der Adresse 0Ah im Programmspeicher den Namen LCD_RAM?
Ich denke das sollte IDATA heißen.

Das zweite ist das du beim initialisieren bereits im 4-Bit Modus sendest. Das darf nicht sein. Zum initilasisieren mußt du das Highnibble so anlegen als wärst du im 8-Bit-Modus und dann Enable pulsen.

Sollte in etwa so aussehen:

lcd-reset:
CLR en
CLR rs
CLR rw

CLR db7
CLR db6
SETB db5
SETB db4
call wait-long

SETB en
CLR en
call wait-long

SETB en
CLR en
call wait-long

SETB en
CLR en
call wait

CLR DB4 ;hier schon im 8-Bit Modus auf 4-Bit umstellen
SETB en
CLR en
RET

Monaco
28.04.2005, 15:05
Das Problem ist dass mein Compiler den Befehl DATA nicht kennt desshalb habe ich gedacht mit CODE gehts auch da dieser ja das ganze register anspricht ?
Und Ich hab doch nur 4 Bit angeschlossen dann kann ich doch auch nur 4 bit senden oder ?

Sandro
28.04.2005, 15:38
Wie gesagt, mein Assembler versteht dieses CODE garnicht. Aber ich denke das du damit nur den CODEspeicher deklarieren kannst. Versuch doch mal ein EQU. Bei mir geht das.

Und das du nur 4-Bit angeschlossen hast ist klar. Aber bei der initialisierung tust du einfach so als wären es 8.

Leg einfach nur das Highnibble ans Display an und pulse Enalble. So wie in dem Code den ich oben geschrieben hab. Das Bitmuster zum Reset war bei dir auch nicht richtig. Du mußt genau das Bitmuster aus dem Datenblatt senden.
Nach dem Reset mußt du dann das Bit für den 4-Bit Modus stellen und wieder Enable pulsen.

Ab jetzt kannst du im 4-Bit-Modus arbeiten.
Und als erstes sendest du den "Function Set"-Befehl. Der wird nämlich nur an dieser Stelle akzeptiert.

Und ein kleiner Fehler ist mir gerade noch aufgefallen:

LCD_send:
call LCD_ws ;hier muß noch eine Wartezeit rein da du das Busy nicht abfragst

MOV C,ACC.7 ; high-nibble ausgeben
MOV LCD_D7,C
MOV C,ACC.6
MOV LCD_D6,C
MOV C,ACC.5
MOV LCD_D5,C
MOV C,ACC.4
MOV LCD_D4,C

SETB LCD_ENABLE
; call LCD_ws ;bei mir ist das nicht nötig, prozessor so schnell?
CLR LCD_ENABLE

call LCD_ws ;hier muß noch eine Wartezeit rein da du das Busy nicht abfragst

MOV C,ACC.3 ; low-nibble ausgeben
MOV LCD_D7,C
MOV C,ACC.2
MOV LCD_D6,C
MOV C,ACC.1
MOV LCD_D5,C
MOV C,ACC.0
MOV LCD_D4,C

SETB LCD_ENABLE
; call LCD_ws
CLR LCD_ENABLE

RET

Hab reingeschrieben was mir noch aufgefallen ist.

Monaco
28.04.2005, 15:41
Also ich muss sagen ich bin eher ein leihe was sagen Assembler angeht und ich kann dir leider nicht ganz folgen. Würdest du mir den code so ändern dass er funktioniert ? wäre seh sehr nett

Sandro
28.04.2005, 15:52
Das du dich noch nicht so gut auskennst macht ja nichts. Vieleicht hab ich mich auch nicht klar genug ausgedrückt.
Ändern möchte ich deinen Code allerdings nicht.
Der Lerneffekt ist viel größer wenn du es selbst schaffst.
Aber wenn du wirklich nicht weiterkommst kann ich dir Code von mir schicken an dem du dich orientieren kannst.
Wenn du das willst dann schreib mir.

Monaco
28.04.2005, 16:11
Das wäre nicht schön, denn wenn ich was durchlese verstehe ich es meist leicher.

Sandro
28.04.2005, 16:25
Gut.
Ich hab mal bisschen was rausgesucht.
Damit sollte die Initialisierung und das Senden schonmal funktionieren.
Ist aber kein vollständiges Programm.


INCLUDE ....... ;dein prozessor

;-------------------------------------------------------------------------------
;variablendeklaration
rs EQU px.x
rw EQU px.x
en EQU px.x
DB4 EQU px.x
db5 EQU px.x
db6 EQU px.x
db7 EQU px.x
;-------------------------------------------------------------------------------



;-------------------------------------------------------------------------------------
lcd-com:
;sendet einen Befehl im ACC ans LCD
CLR rs
CLR rw
JMP lcd-write
;-------------------------------------------------------------------------------------
lcd-out:
;sendet ein Zeichen im ACC ans LCD
SETB rs
CLR rw
;-------------------------------------------------------------------------------------
lcd-write:
;beeinflusst ACC,Carry und R0-R2
MOV R2,#02h ;zwei durchläufe da zwei nibbles
lcd-write1:
call wait ;es könnte kurz vorher gesendet worden sein also lieber
;mal etwas warten bis das lcd bereit ist
RLC A ;daten
MOV db7,C ;schrittweise
RLC A ;in carry schieben
MOV db6,C ;und an datenport
RLC A ;anlegen
MOV db5,C
RLC A
MOV db4,C

SETB en ;schreibimpuls
CLR en

DJNZ R2,lcd-write1 ;wiederholen wenn es der erste durchlauf war
RET
;-------------------------------------------------------------------------------------


;-------------------------------------------------------------------------------------
lcd-ini:
CLR en
CLR rs
CLR rw

CLR db7 ;lcd
CLR db6 ;8-bit
SETB db5 ;modus
SETB db4 ;
call wait-long ;länger warten

SETB en ;
CLR en ;senden
call wait-long ;länger warten

SETB en ;nochmal
CLR en ;senden
call wait-long ;länger warten

SETB en ;nochmal
CLR en ;senden
call wait ;länger warten

CLR DB4 ;4-bit modus
SETB en ;senden
CLR en

;-------------------------------------------------------------------------------------
;dispalyfunktionen initialisieren
MOV A,#28h ;4bit, 2lines, 5x7
call lcd-com
MOV A,#01h ;clr
call lcd-com
MOV A,#02h ;home
call lcd-com
MOV A,#06h ;inc no shift
call lcd-com
MOV A,#0ch ;disp. on ,curs. off ,blink off
call lcd-com
RET
;-------------------------------------------------------------------------------------
wait-long:
;evtl die register retten wenn du sie brauchst
MOV R0,#00h
MOV R1,#00h
wait-long1:
DJNZ R0,wait-long1
DJNZ R1,wait-long1
RET
;-------------------------------------------------------------------------------------
wait:
;evtl register retten wenn du sie brauchst
MOV R0,#00h
wait1:
DJNZ R0,wait1
RET
;-------------------------------------------------------------------------------------

Damit solltest du schon weiterkommen.
Ist aus einem funktionstüchtigen Programm. Sollte also klappen.

Monaco
28.04.2005, 16:34
Was bedeutet das include Prozessor ?

Sandro
28.04.2005, 17:00
Das ist eine include-Anweisung.
Der Assembler, oder besser der Präprozessor, geht vor dem assemblieren das Programm durch und sucht nach solchen Anweisungen.
Diese soll die Header-datei des verwendeten Prozessors mit einbinden. Darin sind dann die ganzen SFRs bezeichnet. Machst du das nicht würde der Assembler nicht verstehen was du z.B. mit P1 meinst.
Musst du das nicht machen?
Mein Assembler beschwert sich wenn es nicht da seht. Welchen benutzt du?

Monaco
28.04.2005, 17:03
Mhh ich hab den Code den du mir gegeben hast in meinem Programm geändert aber es funktioniert immernoch nicht.

kannst du mir mal das ganze Programm geben ?

Monaco
28.04.2005, 17:05
Mir hat man gesagt, dass ich an Enable einfach GND anschließen kann. Aber wie da jetzt dann funktioniert weiss ich auch wieder nicht.
Ein Freund hat mir mal ein kleines Programm mit Bascom geschrieben um den Display zu testen, das hat auch Funktioniert, aber auch nur bei einem meiner 2 Display ich hoffe mal nicht dass die Displays wieder kaputt sind.

Monaco
28.04.2005, 17:09
Wo bekomme ich eine Solche Präprozessor Datei für meinen MC ?
Wenn du ICQ hast und du mir noch helfen magst kannst du mich adden
110329443

MFG

Schwabix
28.04.2005, 17:09
Hallo,

Ich habe hier auch noch ein paar Display-Routinen zum Stöbern. Die bedienen das Teil zwar im 8-bit-Modus, dafür ist ist das Warten auf das Display sauber gelöst und es gibt Ausgaberoutinen für div. Datentypen.



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; TASM source: display.inc
; display constants and routines for ES535
; Processor: 8051(80535?) on ES535 + DisplayTech 164A
;
; Hardware: 8000h display command port (memory mapped)
; 8001h display data write port (memory mapped)
; 8002h display status port (memory mapped)
; 8003h display data read port (memory mapped)
; Routines:
; ds_init Init display, clear, cursor home
; ret: A=0 no display, A=1 display ok
; ds_busy Wait until display not busy
; ds_clear clear display
; ds_cursor set cursor to A=lc (nibbles for line/column)
; ds_write display zero delimited string at DPTR
; ds_int display A as a dezimal integer
; ds_hex display A as a hexadezimal byte
;
; (c) 2003, M.Kuhn, aka "Schwabix"


DISP_CMD .EQU 8000h
DISP_WR .EQU 8001h
DISP_BSY .EQU 8002h
DISP_RD .EQU 8003h


ds_init push DPH
push DPL
acall ds_busy
mov DPTR,#DISP_CMD
mov A,#40H ; read CGRAM @0
movx @DPTR,A
acall ds_busy
mov DPTR,#DISP_RD
movx A,@DPTR
mov B,A
acall ds_busy
mov DPTR,#DISP_CMD
mov A,#4FH ; read CGRAM @F
movx @DPTR,A
acall ds_busy
mov DPTR,#DISP_RD
movx A,@DPTR

xrl A,B ; both equal?
jnz disp_ok
mov A,#0
sjmp di_exit

disp_ok acall ds_busy
mov DPTR,#DISP_CMD
mov A,#38H ; 8bit, 2lines, 5x7dots
movx @DPTR,A
acall ds_busy
; mov DPTR,#DISP_CMD
mov A,#06H ; inc, no shift
movx @DPTR,A
acall ds_busy
; mov DPTR,#DISP_CMD
mov A,#0CH ; lcd on, no cursor/blink
; mov A,#0FH ; lcd on, cursor/blink
movx @DPTR,A
acall ds_busy
; mov DPTR,#DISP_CMD
mov A,#01H ; clear
movx @DPTR,A

acall ds_busy
mov DPTR,#DISP_CMD
mov A,#80H ; cursor home
movx @DPTR,A

mov A,#1
di_exit pop DPL
pop DPH
ret

ds_busy push DPH
push DPL
db_1 mov DPTR,#DISP_BSY
movx A,@DPTR
jb ACC.7,db_1
pop DPL
pop DPH
ret

ds_clear push DPH
push DPL
acall ds_busy
mov DPTR,#DISP_CMD
mov A,#01H ; clear display
movx @DPTR,A
pop DPL
pop DPH
ret

; this is valid only for 4x16 displays
crs_tab .DB 80h, 0C0h, 90h, 0D0h

ds_curs push DPH
push DPL
push ACC
acall ds_busy
pop ACC
mov B,A
anl B,#0Fh
swap A
anl A,#0Fh
mov DPTR,#crs_tab
movc A,@A + DPTR
add A,B

mov DPTR,#DISP_CMD
movx @DPTR,A
pop DPL
pop DPH
ret

ds_write mov R0,DPL
mov R1,DPH
dw_1 acall ds_busy
mov DPL,R0
mov DPH,R1
mov A,#00
movc A,@A + DPTR
jz dw_exit
inc DPTR
mov R0,DPL
mov R1,DPH
mov DPTR,#DISP_WR
movx @DPTR,A
sjmp dw_1
dw_exit ret


ds_int push DPH
push DPL
mov R0,A
di_1 acall ds_busy
mov A,R0
mov B,#100
div AB
mov R0,B
jnz di_2
mov A,R0
mov B,#10
div AB
mov R0,B
jnz di_3
sjmp di_4

di_2 orl A,#30h
mov DPTR,#DISP_WR
movx @DPTR,A
acall ds_busy
mov A,R0
mov B,#10
div AB
mov R0,B
di_3 orl A,#30h
mov DPTR,#DISP_WR
movx @DPTR,A
di_4 acall ds_busy
mov A,R0
orl A,#30h
mov DPTR,#DISP_WR
movx @DPTR,A
di_exi1 pop DPL
pop DPH
ret

ds_0int push DPH
push DPL
mov R0,A
d0i_1 acall ds_busy
mov A,R0
mov B,#100
div AB
mov R0,B
jnz d0i_2
mov A,R0
mov B,#10
div AB
mov R0,B
sjmp d0i_3

d0i_2 orl A,#30h
mov DPTR,#DISP_WR
movx @DPTR,A
acall ds_busy
mov A,R0
mov B,#10
div AB
d0i_3 mov R0,B
orl A,#30h
mov DPTR,#DISP_WR
movx @DPTR,A
acall ds_busy
mov A,R0
orl A,#30h
mov DPTR,#DISP_WR
movx @DPTR,A
pop DPL
pop DPH
ret

ds_hex push DPH
push DPL
mov R0,A
acall ds_busy
mov A,R0
swap A
anl A,#0Fh
acall make_dig
mov DPTR,#DISP_WR
movx @DPTR,A
acall ds_busy
mov A,R0
anl A,#0Fh
acall make_dig
mov DPTR,#DISP_WR
movx @DPTR,A
pop DPL
pop DPH
ret
make_dig orl A,#30h
mov B,A
setb C
subb A,#39h
mov A,B
jc lt9
add A,#'A'-'9'-1
lt9 ret


.end


Das gehört zu meinen ersten 8051-Routinen überhaupt ... =:-O

Schwabix

Monaco
28.04.2005, 17:15
Wie ändere ich das nun um in 4 BIT ?

Sandro
28.04.2005, 17:40
@Monaco

Die Headerdatei kannst du auch selbst schreiben fals sie nicht dabei sein sollte.
Einfach den "SFR-Namen EQU die SFR-Adresse".
z.B. P1 EQU 90h
Aber für gewöhnlich sind da immer ein paar dabei. Was benutzt du den für einen Assembler?
Enable auf GND zu legen kann nicht funktionieren. Das LCD übernimmt die Daten mit einer steigenden Flanke an Enable.
RW kann man auf GND legen wenn man möchte. Damit verbaust du dir aber dann die Möglichkeit vom LCD zu lesen.
Was ich dir geschickt hab sollte schon Funktionieren. Hast du die Möglichkeit das andere Display mal dranzuhängen?
Oder dieses im 8-Bit-Modus zu betreiben?


@Schwabix

Mit dem Bussy hast du recht. Das ist keine saubere Lösung. Aber soweit ich weiß muß man auch beim lesen der Daten eine Pause einlegen. Das würde mich noch mehr ausbremsen.
Was du da geschrieben hast gefällt mir aber sehr gut.
Und ich glaub fast jeder wagt sich als erstes mal an ein LCD. Mich eingeschlossen.

Minifriese
07.05.2005, 16:26
ds_busy push DPH
push DPL
db_1 mov DPTR,#DISP_BSY
movx A,@DPTR
jb ACC.7,db_1
pop DPL
pop DPH
ret

Moin!

Hab ich das richtig verstanden, diese Routine wartet darauf, dass das Display nicht mehr "busy" ist? Dann ist bei dir wohl ACC.7 das Busy-Flag. Auf welchem Pin des Displays liegt denn das? Im Conrad-Datenblatt taucht es nicht auf, jedenfalls nicht unter diesem Namen??

Nils

Sandro
07.05.2005, 18:03
Um das Busy eines LCDs zu testen muß man einen der beiden Adresscounter lesen. Welchen du liest ist egal. Das höchste Bit stellt immer das Busyflag dar.
Schau dir im Datenblatt mal die Befehlstabelle an. Da gibts einen Befehl der heißt "READ BUSY FLAG & ADRESS".
Ein seperater Pin am Display ist nicht vorhanden.

Minifriese
08.05.2005, 15:05
Moin moin!

Hab mein LCD-Display zumindest mal initialisiert bekommen. Glaub ich wenigstens. Nach Ablauf dieses Programms


// Ansteuerung eines 16*2-Zeichen LCDs (44780-kompatibel)

#include <avr\io.h>

#define CPU_CK 8000000
#define LCD PORTB

#define DB4 0
#define DB5 1
#define DB6 2
#define DB7 3
#define ENABLE 4
#define RW 5
#define RS 6
#define CONTRAST 7

void waitus(int d) { // Feste Anzahl von Mikrosekunden warten
int i,a;
for(i=0;i<(d/(CPU_CK/1000));i++) {
a=i; // Eigentlich "asm:nop", Syntax??
}
}

void init(void) {
DDRB = 0xFF;
//-------------------------------------------------------------------------------------------
waitus(15000);
LCD = (1<<ENABLE);
LCD |= (1<<DB4)|(1<<DB5); // DB4 und DB5 setzen
waitus(1000);
LCD &= ~(1<<ENABLE);
//-------------------------------------------------------------------------------------------
waitus(5000);
LCD = (1<<ENABLE);
LCD |= (1<<DB4)|(1<<DB5); // DB4 und DB5 setzen
waitus(1000);
LCD &= ~(1<<ENABLE);
//-------------------------------------------------------------------------------------------
waitus(1000);
LCD = (1<<ENABLE);
LCD |= (1<<DB4)|(1<<DB5); // DB4 und DB5 setzen
waitus(1000);
LCD &= ~(1<<ENABLE);
//-------------------------------------------------------------------------------------------
waitus(1000);
LCD = (1<<ENABLE);
LCD |= (1<<DB5); // DB5 setzen (4bit-Modus aktivieren)
waitus(1000);
LCD &= ~(1<<ENABLE);
//-------------------------------------------------------------------------------------------
waitus(1000);
LCD = (1<<ENABLE);
LCD |= (1<<DB5); // DB5 setzen (4bit-Modus)
waitus(1000);
LCD &= ~(1<<ENABLE);

waitus(1000);
LCD = (1<<ENABLE);
LCD |= (1<<DB7); // DB7 setzen (2-zeiliges Display)
waitus(1000);
LCD &= ~(1<<ENABLE);
//-------------------------------------------------------------------------------------------
waitus(1000);
LCD = (1<<ENABLE);
waitus(1000); // Leeres Nibble
LCD &= ~(1<<ENABLE);

waitus(1000);
LCD = (1<<ENABLE);
LCD |= (1<<DB7)|(1<<DB6)|(1<<DB5); // Display on, Cursor on
waitus(1000);
LCD &= ~(1<<ENABLE);
//-------------------------------------------------------------------------------------------
waitus(1000);
LCD = (1<<ENABLE);
waitus(1000); // Leeres Nibble
LCD &= ~(1<<ENABLE);

waitus(1000);
LCD = (1<<ENABLE);
LCD |= (1<<DB4); // Clear Display
waitus(1000);
LCD &= ~(1<<ENABLE);
//-------------------------------------------------------------------------------------------
waitus(1000);
LCD = (1<<ENABLE);
waitus(1000); // Leeres Nibble
LCD &= ~(1<<ENABLE);

waitus(1000);
LCD = (1<<ENABLE);
LCD |= (1<<DB6)|(1<<DB5); // Increment Cursor after writing
waitus(1000);
LCD &= ~(1<<ENABLE);
}

int main(void) {
init();
//-------------------------------------------------------------------------------------------
waitus(15000);
LCD = (1<<ENABLE)|(1<<RS);
LCD |= (1<<DB5)|(1<<DB4); // Erstes Nibble=0x3
waitus(1000);
LCD &= ~(1<<ENABLE);

waitus(1000);
LCD = (1<<ENABLE)|(1<<RS);
waitus(1000); // Zweites Nibble=0x0, zusammen "0"
LCD &= ~(1<<ENABLE);
//-------------------------------------------------------------------------------------------
waitus(15000);
LCD = (1<<ENABLE)|(1<<RS);
LCD |= (1<<DB6); // Erstes Nibble=0x4
waitus(1000);
LCD &= ~(1<<ENABLE);

waitus(1000);
LCD = (1<<ENABLE)|(1<<RS);
LCD |= (1<<DB7)|(1<<DB6)|(1<<DB5); // Zweites Nibble=0xE, zusammen "N"
waitus(1000);
LCD &= ~(1<<ENABLE);
}

im ATm16 zeigt mein Display einen Cursor in der ersten Zeile auf Position eins. Von der Initialisierung her sollte das auch stimmen, bloss wird anscheinend der Code in main() nicht ausgefuehrt. Da sollte naemlich eine "0" und ein "N" geschrieben werden, der cursor ruehrt sich aber kein Stueck.

Kann mal jemand drueberschauen? Ich hab schon son leichten Tunnelblick und find den Fehler nich...

Danke,

Nils