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 ?
Druckbare Version
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 ?
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.
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
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.
Das gehört zu meinen ersten 8051-Routinen überhaupt ... =:-OCode:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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
Schwabix
Wie ändere ich das nun um in 4 BIT ?
@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.
Moin!Code: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
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
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.
Moin moin!
Hab mein LCD-Display zumindest mal initialisiert bekommen. Glaub ich wenigstens. Nach Ablauf dieses Programms
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.Code:// 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);
}
Kann mal jemand drueberschauen? Ich hab schon son leichten Tunnelblick und find den Fehler nich...
Danke,
Nils