Was mach ich falsch? LCD-Ansteuerung

Gast #955738
Lesenswert?

Hallo,

wollte mal ein LCD ansteuern und hab das Tutorial verwendet. Nun wollte 
ich zunächst das Programm in den Controller (ATmega8) übertragen.

Ich hab also die lcd_routines.asm in einen Ordner gespeichert und auch 
das Testprogramm, das das Wort Test auf dem Display abbilden soll.

Beim Assemblieren kommt jedoch die Fehlermeldung


... error: Invalid register
... error: Undefined symbol: PORTD
... error: Undefined symbol: temp1
[...] das ganze noch ein paar mal
und unten:
... No EEPROM data, deleting ...\mega8.eep

Assembly failed, 72 errors, 0 warnings
Gast #956013
Lesenswert?

achso, also der Code sieht so aus:

.include "m8def.inc"

.def temp1 = r16
.def temp2 = r17
.def temp3 = r18


           ldi temp1, LOW(RAMEND)      ; LOW-Byte der obersten 
RAM-Adresse
           out SPL, temp1
           ldi temp1, HIGH(RAMEND)     ; HIGH-Byte der obersten 
RAM-Adresse
           out SPH, temp1

           ldi temp1, 0xFF    ; Port D = Ausgang
           out DDRD, temp1

           rcall lcd_init     ; Display initialisieren
           rcall lcd_clear    ; Display löschen

           ldi temp1, 'T'     ; Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 'e'     ; Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 's'     ; Zeichen anzeigen
           rcall lcd_data

           ldi temp1, 't'     ; Zeichen anzeigen
           rcall lcd_data

loop:
           rjmp loop

 ;sendet ein Datenbyte an das LCD
lcd_data:
           mov temp2, temp1             ; "Sicherungskopie" für
                                        ; die Übertragung des 2.Nibbles
           swap temp1                   ; Vertauschen
           andi temp1, 0b00001111       ; oberes Nibble auf Null setzen
           sbr temp1, 1<<4              ; entspricht 0b00010000 (Anm.1)
           out PORTD, temp1             ; ausgeben
           rcall lcd_enable             ; Enable-Routine aufrufen
                                        ; 2. Nibble, kein swap da es 
schon
                                        ; an der richtigen stelle ist
           andi temp2, 0b00001111       ; obere Hälfte auf Null setzen
           sbr temp2, 1<<4              ; entspricht 0b00010000
           out PORTD, temp2             ; ausgeben
           rcall lcd_enable             ; Enable-Routine aufrufen
           rcall delay50us              ; Delay-Routine aufrufen
           ret                          ; zurück zum Hauptprogramm

 ; sendet einen Befehl an das LCD
lcd_command:                            ; wie lcd_data, nur RS=0
           mov temp2, temp1
           swap temp1
           andi temp1, 0b00001111
           out PORTD, temp1
           rcall lcd_enable
           andi temp2, 0b00001111
           out PORTD, temp2
           rcall lcd_enable
           rcall delay50us
           ret

 ; erzeugt den Enable-Puls
 ;
 ; Bei höherem Takt (>= 8 MHz) kann es notwendig sein,
 ; vor dem Enable High 1-2 Wartetakte (nop) einzufügen.
 ; Siehe dazu Beitrag "Re: Bitte helft mir. Schon wieder AtMega16"
lcd_enable:
           sbi PORTD, 5                 ; Enable high
           nop                          ; 3 Taktzyklen warten
           nop
           nop
           cbi PORTD, 5                 ; Enable wieder low
           ret                          ; Und wieder zurück

 ; Pause nach jeder Übertragung
delay50us:                              ; 50us Pause
           ldi  temp1, $42
delay50us_:dec  temp1
           brne delay50us_
           ret                          ; wieder zurück

 ; Längere Pause für manche Befehle
delay5ms:                               ; 5ms Pause
           ldi  temp1, $21
WGLOOP0:   ldi  temp2, $C9
WGLOOP1:   dec  temp2
           brne WGLOOP1
           dec  temp1
           brne WGLOOP0
           ret                          ; wieder zurück

 ; Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
lcd_init:
           ldi  temp3,50
powerupwait:
           rcall  delay5ms
           dec  temp3
           brne powerupwait
           ldi temp1, 0b00000011        ; muss 3mal hintereinander 
gesendet
           out PORTD, temp1             ; werden zur Initialisierung
           rcall lcd_enable             ; 1
           rcall delay5ms
           rcall lcd_enable             ; 2
           rcall delay5ms
           rcall lcd_enable             ; und 3!
           rcall delay5ms
           ldi temp1, 0b00000010        ; 4bit-Modus einstellen
           out PORTD, temp1
           rcall lcd_enable
           rcall delay5ms
           ldi temp1, 0b00101000        ; 4Bit  2 Zeilen  5x8
           rcall lcd_command
           ldi temp1, 0b00001100        ; Display ein  Cursor aus  
kein Blinken
           rcall lcd_command
           ldi temp1, 0b00000100        ; inkrement / kein Scrollen
           rcall lcd_command
           ret

 ; Sendet den Befehl zur Löschung des Displays
lcd_clear:
           ldi temp1, 0b00000001   ; Display löschen
           rcall lcd_command
           rcall delay5ms
           ret

 ; Sendet den Befehl: Cursor Home
lcd_home:
           ldi temp1, 0b00000010   ; Cursor Home
           rcall lcd_command
           rcall delay5ms
           ret


Ich verwende das AVR Studio 4 !
Gast #956040
Lesenswert?

AVRASM: AVR macro assembler version 1.77.3 (Dec 20 2006 14:29:41)
Copyright (C) 1995-2005 ATMEL Corporation


Assembling 'C:\Temp\lcd.asm'
Including  'C:\Programme\Atmel\AVR 
Tools\AvrAssembler\Appnotes\m8def.inc'

Program memory usage:
Code             :   87 words
Constants (dw/db):    0 words
Unused           :    0 words
Total            :   87 words

Assembly complete with no errors.


Ich bekomme keine Fehlermeldungen!
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren