Forum: Mikrocontroller und Digitale Elektronik Problem mit AVR-Tutorial im LCD-Teil


von Moritz S. (moritz_s)


Lesenswert?

Hallo,

Ich bin gerade dabei das AVR-Tutorial durchzuarbeiten, bisher 
funktioniert auch alles. Nun bin ich bei dem Teil mit dem LCD, aber ich 
bekomme einfach nichts angezeigt denn auf dem Display ist nur wie 
beschrieben die Eine Zeile Schwarz. Wisst ihr woran das liegen könnte ? 
Ich habe zig mal den Anschluss durchgemessen, alles ist Richtig 
angeschlossen. Ich nutze einen ATMega auf einem Atmel Evaluationsboard 
von Pollin. Wie gesagt bisher hat alles funktioniert (Mit den Leds, 
Tastern usw.) Woran könnte es liegen das mein LCD die Buchstaben 'Test' 
die in dem Code geschrieben sind nicht ausgibt? Könnte es daran liegen 
das ich das Falsche Quarz habe, denn auf dem Atmelboard ist ja ein 16Mhz 
Quarz, wenn ich aber in der LCD-Routine.asm XTAL auf 16000000 stellen 
möchte sagt er mir beim Erstellen "Operand(s) out of range in 'ldi 
r16,0x10a'. Eigentlich müsste das mein Problem sein denn sonst ist alles 
wie im Tutorial beschrieben.

Ich hoffe ihr könnt mir helfen.

MFG Moritz S.

von spess53 (Gast)


Lesenswert?

Hi

>"Operand(s) out of range in 'ldi r16,0x10a'

0x10A passt nicht in ein 8 Bit Register.

MfG Spess

von Moritz S. (moritz_s)


Lesenswert?

Aber wieso tritt der Fehler nur auf wenn ich die 16Mhz (16000000) 
einstellen möchte? Wenn ich das Standart lasse lässt es sich Compilieren 
aber das Display bleibt nach wie vor Leer. Wie ihr bestimmt schon 
gemerkt habt bin ich ein absoluter Anfänger, und habe keine Ahnung wie 
ich dies:

spess53 schrieb:
>>"Operand(s) out of range in 'ldi r16,0x10a'
>
> 0x10A passt nicht in ein 8 Bit Register.

beheben kann.

Könntet ihr mir Helfen?

MFG

von spess53 (Gast)


Lesenswert?

Hi

>Aber wieso tritt der Fehler nur auf wenn ich die 16Mhz (16000000)
>einstellen möchte?

Dazu müsste man wissen, an welcher Stelle das auftritt.

MfG Spess

von Moritz S. (moritz_s)


Lesenswert?

Also in der LCD-Routines Datei gibt es eine Stelle die lautet so:
1
 
2
; Pause nach jeder Übertragung
3
delay50us:                              ; 50us Pause
4
           ldi  temp1, ( XTAL * 50 / 3 ) / 1000000
5
delay50us_:
6
           dec  temp1
7
           brne delay50us_
8
           ret                          ; wieder zurück

Laut der Fehlermeldung (Operand(s) out of range in 'ldi
r16,0x10a') sollte es genau in diesen Zeilen irgendwo liegen.

Hier zeige ich nochmal wie ich den Quarztakt eingestellt habe:
1
.ifndef XTAL
2
.equ XTAL = 16000000
3
.endif
Dies steht ganz am Anfang der LCD-Routines Datei. Selbstverständlich 
habe ich das Externe Quarz eingestellt (Fuses).

MFG

von ... (Gast)


Lesenswert?

Moritz S. schrieb:
> .equ XTAL = 16000000

Bist du sicher, dass der Compiler das als Long Datentyp interpretiert?

von Moritz S. (moritz_s)


Lesenswert?

Nein, wie stelle ich sowas den fest, und wie kann ich das beheben?

von spess53 (Gast)


Lesenswert?

Hi

Dann rechne doch mal '( XTAL * 50 / 3 ) / 1000000' mal per Hand aus.


Das sollte funktionieren:
1
delay50us:                              ; 50us Pause
2
           ldi  temp1, ( XTAL * 25 / 3 ) / 1000000
3
delay50us_:
4
           nop 
5
           dec  temp1
6
           brne delay50us_
7
           ret                          ; wieder zurück


MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

>Bist du sicher, dass der Compiler das als Long Datentyp interpretiert?

Assembler kennt kein 'Long'.

MfG Spess

von Thorsten S. (thosch)


Lesenswert?

Hallo Moritz,

anscheinend hast Du das Tutorial nicht richtig gelesen, da steht nämlich 
unter den Delayfunktionen:
--Zitat--
1
Ein kleines Problem kann bei der Verwendung dieses Verfahrens entstehen:
2
Bei hohen Taktfrequenzen und großen Wartezeiten kann der berechnete Wert größer als 255
3
werden und man bekommt die Fehlermeldung "Operand(s) out of range" beim Assemblieren. 
4
Dieser Fall tritt zum Beispiel für obige Konstruktion bei einer Taktfrequenz von 16 MHz ein
5
(genauer gesagt ab 15,3 MHz), während darunter XTAL beliebig geändert werden kann.
6
Als einfachste Lösung bietet es sich an, die Zahl der Takte pro Schleifendurchlauf
7
durch das Einfügen von nop zu erhöhen und die Berechnungsvorschrift anzupassen.
--Zitat-Ende--

Die Berechnung des 8-Bit Schleifenparameters im Unterprogramm delay50us 
gibt bei Taktfrequenzen 15,3 MHz einen Wert größer 0xFF, der dann 
natürlich nicht in ein 8-Bit-Register geladen werden kann und zum 
besagten Fehler führt.

Du mußt die Verzögerungsschleife schon anpassen, wenn sie mit 16 MHz 
funktionieren soll.

Gruß,
Thorsten

von Moritz S. (moritz_s)


Lesenswert?

Achso das habe ich dann wahrscheinlich überlesen. Aber wie ändere ich 
den die Verzögerungsschleifen damit es funktioniert, Wenn ich fragen 
darf?

von spess53 (Gast)


Lesenswert?

Hi

>Das sollte funktionieren:

Da fehlten leider noch zwei 'nop':
1
delay50us:                              ; 50us Pause
2
           ldi  temp1, ( XTAL * 25 / 3 ) / 1000000
3
delay50us_:
4
           nop
5
           nop
6
           nop 
7
           dec  temp1
8
           brne delay50us_
9
           ret                          ; wieder zurück

MfG Spess

von Moritz S. (moritz_s)


Lesenswert?

Ja in der Tat, jetzt lässt es sich Compilieren. Vielen Dank dafür. 
Allerding konnte ich das jetzt auf meinen ATMega16 brennen, aber mein 
Display bleibt immer noch Leer, könnt ihr mir helfen? Habe euch mal die 
Assembler Dateien (AVR-Studio Projekt) angehangen.

von spess53 (Gast)


Lesenswert?

Hi

>Habe euch mal die Assembler Dateien (AVR-Studio Projekt) angehangen.

Nicht wirklich.

MfG Spess

von Moritz S. (moritz_s)


Angehängte Dateien:

Lesenswert?

Mist die Dateien vergessen ;) Jetzt kommen sie aber wirklich.

von Moritz S. (moritz_s)


Lesenswert?

Habe eben nochmal das Display gewechselt um einen Hardwaredefekt oder 
Sonstiges auschließen zukönnen, aber das Display zeigt nach wie vor nur 
die eine Schwarze Zeile an wie im Tutorial nach erfolgreichem Anschluss 
vorgesehen.

von spess53 (Gast)


Lesenswert?

Hi

Na ja, das ist 1:1 aus dem Tutorial kopiert. Habe ich nie benutzt, 
sollte eigentlich funktionieren. Bist du sicher, das am PortD nicht noch 
etwas anderes angeschlossen ist?

MfG Spess

von LcdGast (Gast)


Lesenswert?

Ich hatte gerade das selbe Problem.
Da ich nur drei verschieden farbige Litzen hatte, ist mir der Fehler 
unterlaufen die 4 Datenleitungen falsch herum anzuschließen.
Eventuell solltest du dort mal einen Blick drauf werfen.

von Moritz S. (moritz_s)


Lesenswert?

@LCDGast:
Habe ich ja auch schon nachgeguckt, ist alles wie im Tutorial 
angeschlossen.

@Spess:
Genau fast 1:1 kopiert, nur halt den Quarztakt in der LCDRoutine und den 
ATMega geändert. Darum wundert es mich das es nicht funktioniert.

von spess53 (Gast)


Lesenswert?

Hi

>Darum wundert es mich das es nicht funktioniert.

Deswegen auch meine Frage. Am PortD können auf dem Pöllin-Board lt. 
Schaltplan Leds, Taster, RS232 und Lautsprecher über Jumper angeklemmt 
werden. Sind alle Jumper entfernt?

MfG Spess

von Moritz S. (moritz_s)


Lesenswert?

Ja alle Jumper wurden von mir entfernt, und es besteht auch keine 
verbindung mehr zum RS232 oder sonstigen Ausgabe und Eingabegeräten auf 
dem Board. Rein Theoretische sollte jetzt alles Genau so sein wie im 
Tutorial, aber wie immer funktioniert es bei mir selbst dann nicht.

von Thorsten S. (thosch)


Lesenswert?

Hallo Moritz,

alles deutet darauf hin, daß Dein Display-Controller komplett 
uninitialisiert bleibt. Dann zeigt das LCD in der ersten Zeile einen 
dunkleren Balken...
Wenn Du also keine Falschbeschaltung vorliegen hast, kann es eigentlich 
nur am Timing des Enable-Signals liegen.


Hast Du auch die Anmerkungen im Unterprogramm "lcd_enable" umgesetzt?
Hab ich in Deinem Code jetzt nicht gesehen...
1
; Bei höherem Takt (>= 8 MHz) kann es notwendig sein, 
2
; vor dem Enable High 1-2 Wartetakte (nop) einzufügen. 
3
; Siehe dazu http://www.mikrocontroller.net/topic/81974#685882
4
lcd_enable:
5
           sbi LCD_PORT, PIN_E          ; Enable high
6
           nop                          ; 3 Taktzyklen warten
7
           nop
8
           nop
9
           cbi LCD_PORT, PIN_E          ; Enable wieder low
10
           ret                          ; Und wieder zurück

Sollte dann also für 16 MHz so aussehen:
1
lcd_enable:
2
           nop                          ; zusätzlich 2 Taktzyklen warten
3
           nop
4
           sbi LCD_PORT, PIN_E          ; Enable high
5
           nop                          ; 3 Taktzyklen warten
6
           nop
7
           nop
8
           cbi LCD_PORT, PIN_E          ; Enable wieder low
9
           ret                          ; Und wieder zurück

probier das mal und berichte ...

Gruß,
Thorsten

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.