ein paar Dinge zu Character LC-Displays mit HD44780

rtc

Das ist ein Standard LC-Display, wie es jeder Elektronikhändler im Programm hat. So gut wie jedes LC-Display, daß nur Zeichen darstellen kann, verfügt über einen HD44780 Controller der Fa. Hitachi oder einen seiner kompatiblen Brüder.

Die Ansteuerung ist simpel:
R/W sagt dem IC ob gelesen oder geschrieben werden soll (H:read, L:write)
RS sagt dem IC ob Daten (ein Zeichen) oder ein Befehl gesendet wird (H:data, L:instruction)
DB0-DB7 nehmen das zu schreibende(lesende) byte auf
E(xecute) führt dann den Befehl aus bzw. schreibt/liest das Zeichen

Das Busy-Flag wird ausgelesen, indem man einen Befehl aus dem Controller ausliest, das Statusbyte man erhält. Also R/W auf High um zu lesen und RS auf Low, für Daten. Das 8. Bit ist dann busy. Ist das Bit High ist der Controller noch beschäftigt, also besser warten bis Busy wieder runtergekommen ist. Dann klappts auch mit dem nächsten byte.

ASM Code für nen ATMega32 (also mit CALL)

Die Portbelegung zu den Beispielen:
; LCD mit HD44780
; PA0-PA7	D0-D7 data pins
; PC0		execute
; PC1		R/W
; PC2		RS

1 byte instruction schreiben:
(es wird nur rs gesetzt, das Schreiben selber macht dann lcdwritebyte)
; 1 byte instruction ans lcd senden
lcdtxbytei:
	; write single byte instruction to lcd
	; rgtmp haelt instruction

	; prepare to write instruction
	CBI portc, 2			; rs to low

	; write the byte
	CALL lcdwritebyte

	RET

1 byte daten schreiben:
(es wird nur rs gesetzt, das Schreiben selber macht dann lcdwritebyte)
; end 1 byte daten ans lcd senden
lcdtxbyted:
	; write single byte data to lcd
	; rgtmp haelt databyte

	; prepare to write data
	SBI portc, 2			; rs to high

	; write the byte
	CALL lcdwritebyte

	RET

1 byte schreiben (daten/instruction):
(rs wurde vorher gesetzt, jetzt wird nur noch geschrieben,
am ende wird gewartet, bis der controller fertig ist, busy=low)
; lcd write byte
lcdwritebyte:
	; prepare for write
	SBI portc, 0			; execute to high
	CBI portc, 1			; rw to low

	; porta to output
	LDI rgtmp2, 0xff
	OUT DDRA, rgtmp2
	; copy byte to port
	OUT PORTA, rgtmp

	; lower execute, exec instruction
	CBI portc, 0			; execute to low
	; wait a little
	;CALL Delay10
	NOP

		; --- check busy flag
		; porta to input
		LDI rgtmp2, 0x00
		OUT porta, rgtmp2		; shut down pullups
		OUT DDRA, rgtmp2

		; prepare for busy read
		SBI portc, 1			; rw to high
		CBI portc, 2			; rs to low

		busyloop:
			; read status
			CBI portc, 0			; execute to low
			;CALL delay10
			NOP
			IN rgtmp2, PINA			; read status
			;CALL delay10
			;NOP
			; if busy low, don't run in circles
			SBIS PINA, 7
			RJMP busyend
			SBI portc, 0			; execute to high
			;CALL delay10
			NOP
			RJMP busyloop

		; end of busy
		busyend:

	RET

die Initialisierung des Displays:
(hier für paralleles Interface mit 8Bit, ohne blinkenden cursor(?))
; init display
lcdinit:
	; config execute
	SBI DDRC, 0			; PC0 is output
	SBI PORTC, 0			; and set it to high
	; config rw (read/write, low for write, high for data/status read)
	SBI DDRC, 1			; PC1 is output
	SBI PORTC, 1			; and set it to high
	; config rs (register select, low for instruction, high for data)
	SBI DDRC, 2			; PC2 is output
	SBI PORTC, 2			; and set it to high	

	; init display
	; - 8bit, 2 zeilen
	LDI rgtmp, 0x38
	CALL lcdtxbytei
	; - 8bit, 2 zeilen
	LDI rgtmp, 0x38
	CALL lcdtxbytei
	; - display an, cursor an, blink (?)
	LDI rgtmp, 0x0e
	CALL lcdtxbytei
	; - clear and home display
	LDI rgtmp, 0x01
	CALL lcdtxbytei
	; - autoincrement
	LDI rgtmp, 0x06
	CALL lcdtxbytei

	RET