Tut mir leid das ich schon wieder mit diesem EEPROM Problemen komme. Ich sitze nun aber schon seit zwei Tage vor diesem Poblem, habe das Forum dursucht und die Atmel-Unterlagen gelesen, komme aber einfach nicht weiter! Mein Problem ist das das mein Schreibzugriff nur sehr willkürlich erfolgt. Kann es vieleicht an der Taktung liegen ich habe einen Mega8 mit externen 4 Mhz und den anderen mit den internen 1 Mhz betrieben. Auf dem 4 Mhz bekomme ich meistens gar keine Werte ins EEROM geschrieben. Wenn ich Daten mit Yaap ins EEPROM schreibe gibt es keine Probleme weder mit lesen noch mit schreiben. Wenn ich allerdings mit meinem Testprogramm schreiben will, schreibt er nur ein 00 an die erste Adresse (EEARH=0,EEARL=0) die anderen Bytes sind weiterhinn auf 0xFF. Auf der AVR-Simulation läuft alles bestens!! An meiner Versorgungsspannung dürfte es auch nicht liegne 5V Stabiel bis auf eine Restwelligkeit von 20 mV. Ich habe mein Testprogramm mal angehängt vieleicht findet ihr meinen Fehler. MFG Ben
Was meinst du mit dem Stack? Ich bin erst seit einer Woche am ASM Programmieren und daher weiß ich nicht ob es das ist was du meinst. Also wenn ich den Stackpointer im AVR-Simulator beobachte (SPH-SPL) dann läuft nichts raus er springt sauber auf einen Wert (SPH 0x07, SPL 0xFE) wenn er in die Sub springt und stellt in sauber wieder auf 0x00 beim Rücksprung.
und wo steht in deinem Programm das Laden des SP? Ich sehe nichts.
Habe den Stackpointer nun initialisiert wie im Tut beschreiben. Aber vieleicht bin ich auch auf dem Falschen Weg???? Hänge mein Prog noch mal an... Vielen Dank für deine Mühe...
Ups habe den Stackpointer nur für eine Adresse gestetzt noch mal... Juchei es funktioniert!!!!! Vielen Dank da wäre ich niemals darauf gekommen. Aber vieleicht kannst du mir noch mal erklären wozu ich den Pointer initialisieren muß oder warum das Problem bestand. SO daß ich nicht unwissend sterben muß ;-) Aber ertsmal vielen vielen Dank für die schnelle Hilfe !!!!!
Gehe ich richtig in der Anahme das mein vorheriger Pointer in ein Bereich gezeit hat den es beim Mega8 nicht gibt und er desshalb die Rücksrungadresse nicht gefunden hat? d.h. ich muß beim Prog- beginn immer meinen Stackpointer auf die Oberste Ram- Adrsse setzen das er im richtigen Bereich arbeitet?? oder liege ich damit falsch?
Ich will ja crazy horse seinen Schützling nicht wegnehmen ;) Stack Pointer ist wie er schon heißt nen Stapel-Zeiger und sobald du einen (R)CALL machst (auch Interrupts) dann brauchste diesen Menschen. Bei einem CALL wird die aktuelle Programm-Adresse, wo die Maschine steht- auf den Stack geschmissen, der Stack Pointer springt automatisch bei jedem draufgelegtem Byte eine Adresse tiefer und bei einem abgeholten einen wieder hoch. Initialisiert wird er mit der letzten RAM-Adresse (also ramend) und wenn du dann deine Programmadresse ablegst (2 Bytes) dann liegt das eine Byte auf ramend und das zweite auf ramend-1. Beim RET(I) nimmt der Prozessor die Bytes, die unter dem Pointer und eins höher liegen, auf und nimmt sie wieder in den Adresszähler des µC (wo er sich gerade befindet) und springt somit an den Ort des CALLs zurück. Falls du den Stackpointer nicht initialisiert hast hat er anfangs die Adresse 0x000 und da kann man nicht viel mit machen, er kann keine Adrese beim CALL drauflegen und so nimmt er beim zurückspringen immer die Adresse 0x000 raus, also den Anfang deines Programms. Dave
Mensch da habe ich das Tut gelesen mir aber keine Gedanken über die initialisierung gemacht! Tut mir leid das ich euch wegen sowas belästigen mußte, ihr habt mir aber sehr geholfen. Also dickes Lob an euch!!
Ach, da hab ich ein grosses Herz :-) Bleibt noch zu ergänzen, das der SP nicht zwingend auf RAMEND beim Programmstart zeigen muss, auch wenn das meist die sinnvollste Variante ist. Genausogut könnte der Stack mitten im RAM oder auch RAMStart+x sein, wobei für x die max. benötigte Stacktiefe steht. Der SP ist gnadenlos. Wenn man ihn zwingt, benutzt er auch den I/O und Registerbereich, ebenso stellt es für ihn kein Problem dar, globale Variablen zu überschreiben, es gibt keinerlei Speicherschutzmechanismen, da muss der Programmierer aufpassen. Die Reset-Einstellung 0x0000 ist aber auf jeden Fall unbrauchbar. Legt die Variablen steigend im RAM an und den Stack von oben nach unten, hat man den grösstmöglichen Stackspeicher. Und deswegen wird es auch fast immer so gemacht.
Na das klärt so einiges auch warum bei meinem anderen Programmen der Rücksrung nicht immer geklappt hat. Für ein Hochsprachen verwöhnten Mensch ist es halt doch ein bisschen Umgewöhnung wenn er sich um alles selber kümmern muß ;-) Aber es ist trotzdem ein Traum mal an der Basis die Grundlagen zu lernen und Anwendungen in Echtzeit zu realisieren freu freu freu...
Nur um noch mehr streng geheime Daten aus dem Datenblatt zu erzählen (LOL): Falls du Interrupts aufrufst, so musst du oft die SREG und nen Arbeitsregister speichern. Dafür ist der Stack auch schön geeignet, und zwar mit den Befehlehn PUSH und POP. PUSH r16 legt das Byte in r16 auf den aktuellen Stack-Platz und erniedrigt den Zeiger POP r16 erhöht den Zeiger und nimmt das Byte, das adressiert ist, in r16. Beide Befehle kosten (wie alle RAM-Zugriffe) 2 Takte. Damit, wie crazy horse es beschrieben hat, der liebe Stack dir nicht alles nieder macht im RAM, muss auf ein (R)CALL immer ein RET(I) folgen, sonst gibt es unregelmäßigkeiten. Falls du nach nem CALL KEIN RET machen willst, sondern nen (R)JMP, so bietet es sich an, einfach mal schnell die 2 gePUSHten Adressen runterzuholen: POP register POP register RJMP label und du hascht keine Probleme damit ;) Das mit dem Echtzeit geht doch auch in Basich g, je nachdem wie schnell deine Echtzeit ist lol. dave
Bin gerade dabei miene Fernsteuerung (Ir) an den Mega8 anzubinden. Dachte dabei an eine einfach Lösung Anwendungen zu steuern. Soll ähnlich wie Lirc- Winlirc funktionieren und später auch biderektionell mit dem Pc. So kann ich 1. Daten Austauschen und gleichzeitig auch noch andere Geräte die mit IR funktionieren ansteueren (Steroanlage usw.). Dank eurer Hilfe komme ich nun auch gut vorann. Muß jetzt nur noch das Zeitsignal in ein Binäres umwandeln und schon kann man die Ergebnisse zuordnen- weiterverwenden. Das schlimmste mit dem Stack ist ja das ich das alles schon gelesen habe und dachte auch es verstanden zu haben, aber an die Anfangsadresse hatte ich in meinem Eifer nicht gedacht...
Das hat mich auch gewundert. Der AVR ist ja einer der jüngsten 8-Bitter, warum man da nicht die Erfahrungen anderer einfließen lassen hat. Selbst beim uralten 8051 wird der Stack auf einen gültigen Bereich gesetzt. Und das SREG läßt sich ja nicht mal pushen, einige andere MCs sichern das SREG automatisch bei Interrupts, d.h. das RETI holt dann 3 Bytes vom Stack. Da der AVR ja keine Interruptprioritäten hat, ist es am einfachsten, ein Register nur für die Sicherung des SREG abzustellen, dann braucht man nur ein "IN" und "OUT" zum Sichern im Interrupt. R2 ist da zu empfehlen (R0, R1 werden für LPM, MUL benötigt). Generell ist es sinnvoll, einige Register für Interrupts abzustellen, dann kann man sich PUSH und POP oft ganz sparen. Z.B. reserviere ich den X-Pointer für Interrupts, da für das Hauptprogramm 2 Pointer (Y,Z) völlig ausreichend sind. Peter
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.