Forum: Mikrocontroller und Digitale Elektronik Hilfe LCD SPINNT


von Blutiger Anfänger (Gast)


Lesenswert?

Hi ich habe versucht in den letzten 2wochen das tuturial
durchzuarbeiten.
Ging soweit auch, aber ich habe dann mir ein 4*20 LCD mit entsprchendem
controler wie im T. angegeben.
Bei meinen Mega 8 Typen haut es nicht hin aber bei den 2313 typen schon
die schaltungen sind angepasst und die programierung auch (include
datei), ich möchte aber unbedingt mit den Mega8 typen arbeiten, wer
hatte das selbe problem und weiß eine Lösung ?
Grüße aus Bremen
Andre

von Blutiger Anfänger (Gast)


Lesenswert?

hatte ich ja vergessen (das Wetter puhhh)
das Problem ist : LCD Bleibt dunkel oder keine anzeige manchmal auch
wire Zeichen

von jornbyte (Gast)


Lesenswert?

Im Tuturial geht man von 4MHz Quarz aus. Was für einen hast du?

von Blutiger Anfänger (Gast)


Lesenswert?

benutze einen 4MHZ habe aber auch 2 und 3,556 und 8 MHZ ausprobiert,
ich habe mir eine schaltung augebaut wo ich alles austauschen kann.
Den internen tackt von 1MHZ habe ich auch ausgeschaltet. Programieren
isp geht auch die led steuerung geht auch nur das lcd spinnt und mir
gehen die ideen aus.
Ich habe auch den assembler code geändert und größere interwalle
ausprobiert.....nichts
noch ne Idee ?

von Blutiger Anfänger (Gast)


Lesenswert?

Ich habe gerade mit dem ozzi eine vergleichsmessung gemacht
beim 2313 pd0,pd1,pd3,pd5 1Vss/4Mhz PD2 und PD4 +5V da geht die
anzeige
beim mega8 sind pd0-5 an 1Vss/Mhz
Die Programierung ist bei beiden gleich, Wie kann das angehen ?
Bitte um Tipps
Grüße Andre

von tobias hofer (Gast)


Lesenswert?

hallo

vorweg muss ich sagen ich kenne den mega8 nicht!

aber könnte es sein das die port's die du für die lcd ansteuerung
brauchst beim mega8 opencollector sind? da bräuchtest du dann nähmlich
pullup widerstände.

aber wie gesat ich kenne den mega8 und 2313 nicht, ist nur eine idee.

tobias

von Blutiger Anfänger (Gast)


Lesenswert?

Hi ich habe die LCD routine des funktionsgenratores ausprobiert....
Port D Port B Port B
Nichts......
und der Mega8 hat lt.Datasheet interne pullup Widerstände
ich habe die routinen aus dem T. benutzt.
Wer hat das mit 4*20 Zeichen und den Mega hinbekommen ?
bin echt verzweifelt.... Urlaub um und nicht weiter gekommen...

von Stefan (Gast)


Lesenswert?

Die internen Pullups des Atmega kann man ein und ausschalten, mal im
Datenblatt nachschauen ob sie standartmässig ein oder aus sind, dann
müsste man sie vielleicht einschalten.

Grüsse

von Blutiger Anfänger (Gast)


Lesenswert?

Danke fürn Tipp aber noch ne Idee ?
Grüße

von Merle (Gast)


Lesenswert?

Ich habs schon mal mit nem ATmega8 Probiert bei mir hat es Funktioniert.
Vieleicht hast du vergessen die Definitionsdatei umzuändern also von
.include "2233def.inc" in die Definitionsdatei
.include "m8def.inc" ??

Probiers mal

Mfg. Merle

von Sebastian Wille (Gast)


Lesenswert?

Hast Du auch den Stackpointer (SPH und SPL) angepaßt?

Sebastian

von Merle (Gast)


Lesenswert?

Nö glaub nicht.

Mfg. Merle

von jens (Gast)


Lesenswert?

haun bei dir sie ports hin? ich habe mal (mit nem 85..) ähnliche
probleme gehabt. da gings nach dem einschalten einmale (falls es ging)
danach nie wieder, erst wenn ich aus und wieder eingeschalten habe.
es hat ne weile gedauert, bis ich den fehler fand, denn es ging ja ab
und zu. und das nur wegen fehler in der portprogrammierung.

ciao

von Blutiger Anfänger (Gast)


Lesenswert?

hi die ports funzen aber das mit dem stacks habe ich wohl fasch
gemacht...

so sieht das Programm aus wo ist der fehler ?

.include "m8def.inc"        ;ggf. anpassen

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

           ldi temp1, low(RAMEND)  ;Stackpointer initialisieren
           out SPL, temp1

           ldi temp1, high(RAMEND)
       out sph, temp1

                              ;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

.include "lcd-routines.asm"


lcd-routtines ist original
schonmal Danke für euer nachdenken und die Tipps die ich schon bekommen
habe.
Grüße Andre`

von Merle (Gast)


Lesenswert?

Für was das L beim Stackpointer??

von Blutiger Anfänger (Gast)


Lesenswert?

da steht temp1 (tempeins) und das ist reguister 16
Ist denn mein Programm soweit richtig ?


oder habe ich da beim Stack was falsch gemacht ?

von Merle (Gast)


Lesenswert?

Probiers mal mit nur SP ohne das L.

Mfg. Merle

von Blutiger Anfänger (Gast)


Lesenswert?

dann macht er schon fehler in der copilierung wenn ich das L weg lasse.
spl wird wohl richtig sein.
Danke Merle nochn Tip?
oder jemand anderes ?

von Merle (Gast)


Lesenswert?

Mit welchem Programm arbeitest du denn??

von Merle (Gast)


Lesenswert?

Probier mal ob es Funzt wenn du folgenden code vor 1: schreibst
Der code:
______________________

swap r16

andi r16, 0b00001111

sbr r16, 0b00010000

out PORTD, r16

sbi PORTD, 5

nop

nop

nop

cbi PORTD, 5
________________________

und nach cbi PORTD, 5 kommt dann das Programm über dem die 1: steht
Probiers mal müsste eigentlich funktionieren.

Mfg. Merle

von Blutiger Anfänger (Gast)


Lesenswert?

avr studio 4 und ponny Prog

und der zweite teil meine assembler sieht so aus :
cd_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
           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 ohne RS zu
setzen
           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
lcd_enable:
           sbi PORTD, 5                 ;Enable high
           nop                          ;3 Taktzyklen warten
           nop
       nop
           nop
           cbi PORTD, 5                 ;Enable wieder low
           ret                          ;Und wieder zurück


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

 ;Längere Pause für manche Befehle
delay5ms:                               ;5ms Pause
           ldi  temp1, $31
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        ;noch was einstellen...
           rcall lcd_command
           ldi temp1, 0b00001100        ;...nochwas...
           rcall lcd_command
           ldi temp1, 0b00000100        ;endlich fertig
           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


Biite helft mir ....

von Blutiger Anfänger (Gast)


Lesenswert?

Danke Merle ich probei es gleich aus ! und meld mich dann noch mal
grüße Andre

von Blutiger Anfänger (Gast)


Lesenswert?

Schade das war es nicht.... aber danke für deine mühe Merle
grüße aus Bremen

von Merle (Gast)


Lesenswert?

Warte mal schreib mal dieses Programm:
_______________________________________
swap r16

andi r16, 0b00001111

sbr r16, 0b00010000

out PORTD, r16

sbi PORTD, 5

nop

nop

nop

cbi PORTD, 5


.include "m8def.inc"        ;ggf. anpassen

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

           ldi temp1, RAMEND  ;Stackpointer initialisieren
           out SPL, 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
           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 ohne RS zu
                                        ;setzten
           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
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        ;noch was einstellen...
           rcall lcd_command
           ldi temp1, 0b00001100        ;...nochwas...
           rcall lcd_command
           ldi temp1, 0b00000100        ;endlich fertig
           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

______________________________________________

So das müsste jetzt aber funktionieren hoffe ich zumindest.

Gruß Merle (der Anfänger (leider))
Aber ich denke wir kriegen das schon hin oder?

von Merle (Gast)


Lesenswert?

Und hat der code gefunzt Blutiger Anfänger???

Mfg. Merle

von Blutiger Anfänger (Gast)


Lesenswert?

Danke Merle aber leider nein  das display ist unverändert.
ich hatte auch schon das program von dem funktionsgenerator drinnen und
es so angeschlossen aber auch da hatte ich keine anzeige.
Wenn es nicht mit meine 2313 hinhauen würde, dann würde ich sagen das
display ist kaputt, aber da geht es ja.
ich habe fast 3 wochen versucht das Problem selber zu lösen aber es mag
mich wohl nicht...
So werde ich am Montag als Looser in die Schule gehen und versuchen ob
meinen Dozent für Microprozezortechnik mehr weiß,aber da lehrnen wir
noch aufm 8051 system mit eigenem assembler als Betriebssystem.
etwa 10 Jahre alt und ein Eigenbau des Berufsförderungwerkes.
ich versuch noch die lösung zu finden aber hoffnung ist sehr gering.
Aber Danke an alle die Nachgedacht haben,
besonders Merle.
Falls nochjemand ne Idee  hat nur raus damit
Grüße Andre

von thkais (Gast)


Lesenswert?

Leuts, ihr initialisiert den Stack nicht richtig.
Merle: Das "L" am "SP" ist schon in Ordnung. Nochmal zu den
Grundlagen: Der AVR ist ein 8-Bitter, d.h. jedes Register kann 8 Bit
beinhalten. Also kann man mit 8 Bit 256 Bytes adressieren. Deshalb
gibts beim Mega-8 ein "SPL" und ein "SPH", weil die Kiste 1K SRAM
hat.
In diesem speziellen Fall ist das zwar nicht so relevant, weil ihr den
SRAM nicht anderweitig nutzt, das kann aber zu einer Zeitbombe werden.
Mal ne ganz dumme Idee: Nimm doch mal anstelle Port "D" z.B. Port
"B". Ich habe jetzt nicht das ganze Datenblatt des Mega-8
durchgeackert, aber die Ports haben teilweise Zweitfunktionen. Unter
Umständen könnte eine solche Zweitfunktion per Default ausgewählt sein
- wäre zwar ungewöhnlich, aber man kanns ja mal probieren. Wenns mit
einem 2313 funktioniert, muß es mit dem Mega-8 auch tun.

von Blutiger Anfänger (Gast)


Lesenswert?

Danke für den tip ich habe aber schon port b und c und d ausprobiert.
und den stack habe ich auch versuch zu inizialisieren, siehe oben meine
erstes assemblerprogramm .
da muß ein Fehler sein.Leider kann ich kein englisch und habe
endsprechende schwirigkeiten mit den beschreibungen über den avr und
z.B. mit dem stk500 aber das ist noch ne andere geschichte.
@thkais wo ist den der Fehler in der inizialisierung?

Das ist ne schwere geburt...........

bei so vielen usern hier wird doch schon einer das mit dem mega8
hinbekommen haben oder ? Bitte Tips was mach ich mit sph und spl falsch
?

von henning (Gast)


Lesenswert?

ich hab auch mit ner menge frust experimentiert und verdammt viel
rumgemacht ohne erfolg
alles klappte auf der kleinen version (2313 war das wohl) aber beim
großen (8515 meine ich) gingen nichtmal die grundsätzlichen sachen.
das problem ist das das erste was man überhaupt macht der stack sein
MUSS also:

schön das

.include "m8def.inc"  ;laden
.def temp = r16       ;den Register temp definieren
.def temp2 = r17      ;der ordnung halber die anderen register auch
.def temp3 = r18      ;denn es ist ja nur für den compiler interessant
                      ; und sofort sich um den stack kümmern
ldi temp, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse
out SPL, temp
ldi temp, HIGH(RAMEND); HIGH-Byte der obersten RAM-Adresse
out SPH, temp

danach kannste mit nen paar jump routinen dir das in avrstudio angucken
und überprüfen ob da der stack denn ordnungsgemäß funkzioniert

--> das wird mit hoher warscheinlichkeit das einzige problem sein.
ich hoffe es klappt: viel erfolg!
und melde dich nochmal hier im forum
greez henning

von Tobias Breckle (Gast)


Lesenswert?

hab auch nen mega 8 und bei mir tuts so wie im tutorial.
hab aber glaub was entdeckt:

           ldi temp1, low(RAMEND)  ;Stackpointer initialisieren
           out SPL, temp1

           ldi temp1, high(RAMEND)
       out sph, temp1

                              ;Port D = Ausgang
           out DDRD, temp1

           rcall lcd_init     ;Display initialisiere


wo tust du bei out DDRD, temp1 bestimmen was in temp1 ist??
ich meine du schreibst temp1 mit der adresse des stacks voll und
schreibst das gleiche dann in DDRD. das stimmt doch ned oder??

von Blutiger Anfänger (Gast)


Lesenswert?

@henning Danke so hatte ich das schon eingegeben siehe beitrag 1 über.

@Tobias .def temp1 = r16 habe ich genau davor defeniert
aber bei dir haut es hin? dann kannste ja mir bitte mal deinen
kommpletten quellcode als anhang posten?
villeicht finde ich dann ja meinen Fehler, wäre echt nett von Dir.
Grüße aus Bremen

von henning (Gast)


Lesenswert?

im ersten scriptposting fehlt der befehl vor dem komentar tatsächlich,
nur später ist er dort auch wirklich

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

ich sag mal ich dachte den hab ihr da ;-)

greez henning

von Blutiger Anfänger (Gast)


Lesenswert?

@ henning aber ich werde nochmal im avr studio probieren, aufgeben ist
ja langweilig ,und ich denke es macht keinen unterschied ob ich r16 als
temp oder temp1 defeniere oder ?
Grüße

von Tobias Breckle (Gast)


Lesenswert?

hab des gleiche gemeint wie henning. hat nix mit der definition von
temp1 zu tun.


           ldi temp1, low(RAMEND)  ;Stackpointer initialisieren
           out SPL, temp1

           ldi temp1, high(RAMEND)
       out sph, temp1

>> an der stelle wird temp1 nach DDRD geschrieben.
>> aber was ist denn in temp1 drin?? siehe oben = high(RAMEND)

                              ;Port D = Ausgang
           out DDRD, temp1

           rcall lcd_init     ;Display initialisiere


somit schreibst du high(RAMEND) in temp1 rein.
und eigentlich sollt in temp1 dir portdefinition rein.

von Blutiger Anfänger (Gast)


Lesenswert?

Danke Tobias und Henning es geht das erste mal  jubel grins das war es
 Super jetzt kann ich endlich mal neu sachen testen und dieses nochmal
durcharbeiten.... DANKE DANKE DANKE
grüße Andre aus Bremen

von Tobias Breckle (Gast)


Lesenswert?

nix zu danken :)
freut mich wenn ich au mal jemand helfen konnte und ned immer nur
fragen muss.

von Merle (Gast)


Lesenswert?

:)

von thkais (Gast)


Lesenswert?

Da bist Du nicht der Erste, dem sowas passiert. Nach solchen Fehlern
kann man noch so suchen, man sieht sie meistens nicht... Allerdings ist
in einem solchen Fall der Simulator meistens aufschlußreich.

von hardy (Gast)


Lesenswert?

in deinem ersten posting, wenn das dein programm ist,
fehlt doch die zuweisung für port "d" als ausgang.

ldi  temp1, 0xff   nicht vorhanden
out  ddrd,temp1    vorhanden

von henning (Gast)


Lesenswert?

@Blutiger Anfänger:
freut mich, wenn es jetz klappt, ich hab bei meinem projekt immer
herumprobiert und wieder 2 tage pause gemacht aber als es dann lief
wahren die freudensprünge natürlich verdammt hoch!
ich hasse stack fehler.

@hardy:
das hatten Tobias und ich ja auch schon angemäckelt.

greez henning

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.