Benutzer-Werkzeuge

Webseiten-Werkzeuge


Writing /srv/www/htdocs/udo/singollo.de/linux.singollo.de/public_html/data/cache/5/5bd18982473aa8d4f6cfa8f5ae74f048.metadata failed
hardware:lcd_ea_dog_m162_und_atmega8_4bit

EA DOG-M 162 und ATMega8 mit 4 Bit-Ansteuerung

Ich habe erst vor kurzem angefangen, mich mit dem ATMega8-Controller von Atmel zu beschäftigen. Als erstes Projekt plane ich eine Motorsteuerung mittels PWM für eine Eisenbahn. Für dieses Projekt hatte ich mir als LCD das EA DOG-M162 ausgesucht. Allerdings gab es zum Teil widersprüchliche Angaben oder Codes für andere Prozessorenfamilien. Mit der nachfolgenden Codesequenz lässt sich das Display in Betrieb nehmen (8-Bit an Port D oder 4-Bit an Port D4-7, RS an Port C3 und E an Port C2).

Die weiteren Routinen lcd_string, lcd_number, lcd_number_hex und andere sind hier nicht aufgeführt, da sie den üblichen Libraries für LCDs entnommen werden können. Das Timing orientiert sich an den Zeitangaben im Datenblatt und wertet das Statusregister nicht aus (RW ist fest auf Masse).

Listing

.include "m8def.inc"
 
.equ LCD_PORT = PORTD
.equ LCD_DDR  = DDRD
.equ LCC_PORT = PORTC
.equ LCC_DDR  = DDRC
.equ PIN_RS   = PORTC3
.equ PIN_E    = PORTC2
 
.def temp1 = r16
.def temp2 = r17
.def temp3 = r18
 
.ifndef XTAL
.equ XTAL = 16000000
.endif
 
; Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
lcd_init:
 	ldi   temp1, 255
 	out   LCD_DDR, temp1
 	in    temp1,LCC_DDR
 	sbr   temp1,(1<<PIN_RS)+(1<<PIN_E)
 	out   LCC_DDR,temp1
 	; 50ms warten
 	ldi   temp3,25
powerupwait:
 	rcall delay2ms
 	dec   temp3
 	brne  powerupwait
 	rjmp  lcd_init4              ; Springt die 4-Bit Routine an
;	rjmp  lcd_init8              ; Springt die 8-Bit Routine an
lcd_init4:
 	; Erster Teil der Sequenz manuell starten (siehe Datenblatt ST7036)
 	cbi   LCC_PORT, PIN_RS       ; RS L = command
 	ldi   temp1,0b00110000       ; 8-Bit
	out   LCD_PORT, temp1        ; Ausgeben
 	rcall lcd_enable
 	rcall delay2ms               ; 2ms warten
 	; Zweiter Teil
 	ldi   temp1,0b00110000       ; 8-Bit
 	out   LCD_PORT, temp1        ; Ausgeben
 	rcall lcd_enable
 	rcall delay30us              ; 30us warten
 	ldi   temp1,0b00110000       ; 8-Bit
 	out   LCD_PORT, temp1        ; Ausgeben
 	rcall lcd_enable
 	rcall delay30us              ; 30us warten
	; Ab hier dann die 4-Bit-Sequenz
 	ldi   temp1,0b00100000       ; 4-Bit
 	rcall lcd_command
 	ldi   temp1,0b00101001       ; 4-Bit, 2 Zeilen, Instruction Table 1
 	rcall lcd_command
 	rcall lcd_init_start         ; Gemeinsame Init-Sequenz aufrufen
 	ldi   temp1,0b00101000       ; Instruction Table 0
 	rjmp  lcd_init_end
lcd_init8:
 	ldi   temp1,0b00111001	     ; 8-Bit, 2 Zeilen, Instruction Table 1
 	rcall lcd_command
 	rcall lcd_init_start         ; Gemeinsame Init-Sequenz aufrufen
 	ldi   temp1,0b00111000	     ; Instruction Table 0
; Gemeinsame Init-Sequenz Ende
lcd_init_end:
 	rcall lcd_command            ; Instruction Table 0 aufrufen (temp1 wird vorher gesetzt)
 	ldi   temp1,0b00001100	     ; Display on, Cursor off, Cursor not blinking
 	rcall lcd_command
 	rcall lcd_clear
 	rcall lcd_home
 	ldi   temp1,0b00000110	     ; Entry Mode Set
 	rcall lcd_command
 	ret
; Gemeinsame Init-Sequenz start
lcd_init_start:
 	ldi   temp1,0b00011100	     ; Bias
 	rcall lcd_command
 	ldi   temp1,0b01110100	     ; Kontrast
 	rcall lcd_command
 	ldi   temp1,0b01010010	     ; Booster aus, ICON on, C5/C4 setzen
 	rcall lcd_command
 	ldi   temp1,0b01101001	     ; Follower setzen
 	rcall lcd_command
 	ret
; sendet ein Datenbyte an das LCD
lcd_data:
 	sbi   LCC_PORT, PIN_RS       ; RS H = data
 	rjmp  lcd4
;	rjmp  lcd8
; sendet einen Befehl an das LCD
lcd_command:
 	cbi   LCC_PORT, PIN_RS       ; RS L = command
 	rjmp  lcd4
;	rjmp  lcd8
; Data ausgeben
lcd8:
 	out   LCD_PORT, temp1        ; Ausgeben
 	rcall lcd_enable
 	rcall delay30us
 	ret
lcd4:
 	mov   temp2,temp1            ; Byte sichern
 	andi  temp1, $F0             ; Low-Byte löschen
 	out   LCD_PORT, temp1        ; Ausgeben
 	rcall lcd_enable
 	mov   temp1,temp2            ; Byte zurückholen
 	swap  temp1	             ; Nibbles tauschen
 	andi  temp1, $F0             ; Low-Byte löschen
 	out   LCD_PORT, temp1        ; Ausgeben
 	rcall lcd_enable
 	rcall delay30us
 	ret
; erzeugt den Enable-Puls
lcd_enable:
 	sbi   LCC_PORT, PIN_E        ; Enable high
 	nop
 	nop
 	nop
 	cbi   LCC_PORT, PIN_E        ; Enable wieder low
 	ret                    
; Pause nach jeder Übertragung
delay30us:                           ; 30us Pause
 	ldi   temp1, ( XTAL * 30 / 3 ) / 1000000
delay30us_:
 	dec   temp1
 	brne  delay30us_
 	ret
; Längere Pause für manche Befehle
delay2ms:                            ; 2ms Pause
 	ldi   temp1, ( XTAL * 2 / 607 ) / 1000
WGLOOP0:
 	ldi   temp2, $C9
WGLOOP1:
 	dec   temp2
 	brne  WGLOOP1
 	dec   temp1
 	brne  WGLOOP0
 	ret
; Sendet den Befehl zur Löschung des Displays
lcd_clear:
 	push  temp1
 	ldi   temp1, 0b00000001     ; Display löschen
 	rcall lcd_command
 	rcall delay2ms
 	pop   temp1
 	ret
; Cursor Home
lcd_home:
 	push  temp1
 	ldi   temp1, 0b00000010     ; Cursor Home
 	rcall lcd_command
 	rcall delay2ms
 	pop   temp1
 	ret
hardware/lcd_ea_dog_m162_und_atmega8_4bit.txt · Zuletzt geändert: 07.10.2012 18:31 (Externe Bearbeitung)