;Ansteuerung eines LCD displays mit 4 Zeilen únd 40 Spalten ;Processortakt ist 4Mhz .include "8535def.inc" .def zeichen =r0 .def temp =r16 .def buffer =r17 .def counter =r18 .def position =r19 .equ data = PORTC .equ control = PORTB ;Steuer Port .equ E2 = 0 .equ E1 = 1 .equ RW = 2 .equ RS = 3 .equ BF = 7 .set Timel =0 .set Timeh =0 .cseg .org 0x0030 ini: ldi Temp,Low(RAMEND) ;Stackpointer initialisieren out SPL,Temp ldi Temp,High(RAMEND) out SPH,Temp ldi temp,0xff out DDRB,temp ;PortB ist Output out DDRC,temp ;PortC ist Output inilcd: cbi control,RW ;RW vom display ist 0 ldi temp,0b00111000 ;8Bit Datenbus, 4 Zeilen, 5x7 Zeichen,muss 3 mal gesendet werden rcall outlcd ldi XL,0x0 ;warten c.a.4,1ms ldi XH,0x14 rcall wait ldi temp,0b00111000 ;8Bit Datenbus, 4 Zeilen, 5x7 Zeichen, rcall outlcd ldi XL,0x0 ;warten c.a.4,1ms ldi XH,0x14 rcall wait ldi temp,0b00111000 ;8Bit Datenbus, 4 Zeilen, 5x7 Zeichen, rcall outlcd ldi XL,0x0 ;warten c.a.4,1ms ldi XH,0x14 rcall wait rcall wait_lcd_ok ;Testen ob LCD OK ldi temp,0b00001100 ;Anzeige an , Cursor aus, Blinkcursor aus rcall outlcd ldi XL,0x30 ;c.a.40µs waretn ldi XH,0x00 rcall wait ldi temp,0b00000001 ;Anfangsposition setzen rcall outlcd ldi XL,0xb0 ;c.a. 1,64ms warten ldi XH,0x07 rcall wait rjmp main ;**************************************************************************************** ;** Auf busy flag vom LCD warten ;**************************************************************************************** wait_lcd_ok: clr temp ;PortC ist input out DDRC,temp ;PortC ist input cbi control,RS ;RS ist 0 sbi control,RW ;RW ist 1 (lesen) wb1: sbi control,E1 ;E1 ist high nop nop in temp,PinC ;Lesen vom Display cbi control,E1 ;E1 ist 0 nop sbrc temp,BF ;Testen ob Busy Flag gesetzt rjmp wb1 ;Wenn nicht OK so lange Testen bis OK cbi control,RW ;RW ist 1 (schreiben ) ser temp out DDRC,temp ;PortC ist Output ret ;Rücksprung wenn Busy Flag ok ;**************************************************************************************** ;**************************************************************************************** ;** Hauptprogramm ;**************************************************************************************** main: ldi ZL,low(Zeile_0) ldi ZH,high(Zeile_0) rcall outtext ldi ZL,low(Zeile_1) ldi ZH,high(Zeile_1) rcall outtext ldi ZL,low(Zeile_2) ldi ZH,high(Zeile_2) rcall outtext ldi ZL,low(Zeile_3) ldi ZH,high(Zeile_3) rcall outtext ldi ZL,low(Zeile_0_Spalte_20) ldi ZH,high(Zeile_0_Spalte_20) rcall outtext loop: nop nop rjmp loop ;****************************************************************************************** ;***************************************************************************************** ;** Text auf Display ausgeben ;***************************************************************************************** outtext: ldi temp,0b00000010 ;Anfangsposition setzen rcall outlcd ldi XL,0xb0 ;1,64ms warten ldi XH,0x07 rcall wait ;** Testen ob text in der oberen oder unteren hälfte steht ldi position,0b00001001 ;Enable für E2 setzen RS = 1 in reg position lsl ZL rol ZH sbr ZL,0b00000001 ;MSB von Z-Pointer wird geladen wenn Bit 0 von ZL=1 lpm ;Byte von Z-Pointer laden mov temp,r0 sbrs temp,7 ;Testen ob E1 oder E2 aktiv ldi position,0b00001010 ;Enable für E1 setzen RS = 1 in reg position ;************************************************************************************** ;** Zeile und Spalte wird von Z-Pointer geholt cbr ZL,0b00000001 ;LSB von Z-Pointer wird geladen wenn Bit 0 von ZL=0 lpm mov temp,r0 ori temp,0b10000000 ;LSB Byte von Z-Pointer wird als Zeilen und Spalten positon rcall outlcd ;verwendet adiw ZL,2 ;Z-Pointer + 2 ;****************************************************************************************** ;** Byte für Byte wird von Textadresse gelesen und ausgegeben welche position (oben o. unten) ;** gibt das reg position an das vorher geladen wurde loadtext: ldi XL,0x30 ldi XH,0x00 rcall wait lpm ;Erstes Byte vom Text holen mov temp,r0 cpi temp,0 ;Wenn Byte aus 0x00 besteht ist Textende breq textend mov buffer,position ;E1 oder E2 wird geladen out control,buffer ;und auf 1 gesetzt nop out data,temp ;Byte vom Text wird auf PortB ausgegeben nop clr buffer out control,buffer ;E1 oder E2 werden gelöscht adiw ZL,1 ;Z-Pointer um 1 erhöhen rjmp loadtext textend: ret ;Text ist vollständig ausgegeben worden ;*************************************************************************************** ;** Zeitprogramm wait: sbiw XL,1 brne wait ret ;**************************************************************************************** ;** Steuerbefehle ausgeben outlcd: ldi buffer,0b00000011 ;E1 und E2 auf 1 setzen out control,buffer ;E1 und E2 ausgeben nop nop out data,temp ;Befehle ausgeben nop nop clr buffer out control,buffer ;E1 und E2 löschen ret ;****************************************************************************************** ;** Text der ausgegeben werden soll .org 2000 Zeile_0: .dw 0x0000 .db "Zeile 0" .dw 0x00 Zeile_1: .dw 0x0040 .db "Zeile 1" .dw 0x00 Zeile_2: .dw 0x8000 .db "Zeile 2" .dw 0x00 Zeile_3: .dw 0x8040 .db "Zeile 3" .dw 0x00 Zeile_0_Spalte_20: .dw 0x0013 .db "Zeile_0_Spalte_20" .dw 0x00