Hallo, kann mir das jemand kurz erklären? sts $60,hexl ;low byte speichern wo wird das ganze gespeichert? Im Datenblatt steht Store in Date Space ist damit das SRAM gemeint? Wenn ja kann es mir passieren das diese Speicherstelle durch irgendetwas überschrieben wird z.b. Stapel? Würde das gerne irgendwie verhindern, läßt sich da ein bestimmter Bereich reservieren. Der Hintergrund des ganzen ist folgender ich möchte eine Spannung über den ADC einlesen und 8 Werte fortlaufend speichern um z.b. eine Mittelwertbildung zu machen. Aber 8 Register zu verwenden wäre mir dafür zu schade. Läßt sich dieser Wert auch irgendwie erhöhen damit ich beim 2ten Druchgang $61 habe? Oder kann man da irgendwie mit den Pointern arbeiten. Wäre klasse wenn mir hier jemadn helfen könnte, da ich mich mit der Adressierung in den einzelnen Speicherbereichen garnicht auskenne und das Datenblatt hilft mir hier auch nicht besonderst weiter.
als assembler-programmierer kannst du nur mit .dseg bereiche etwas freihalten, jedoch ist das ein nichtiger schutz im richtigen programm.. man muss halt aufpassen, was man tut zu dem hochzählen: richtig pointer du lädst die adresse des ersten bytes (im sram, also wos erste hin soll) und dann einfach für jedes einmal in x+ speichern.. speichern und automatisches erhöhen des pointers. ldi xl, low(0x60) ldi xh, high(0x60) in r16, adch ; läd das byte st x+, r16 ; speichert es ins sram und erhöht anschließend lesen geht genau so: ld r16, x+ ; lesen und erhöhen weiter gibt es den pre-dec, also erst verkleinern und dann erst was machen: ldi xl, low(0x60+8) ldi xh, high(0x60+8) ld r16, -x wie du es machst ist dir überalassen... manchmal ist es sinnvoll erst alles mit x+ hochzuspeichern und dann nacher mit -x runter holen ==> keine neue adresse in x laden, verdreht dafür dave
Hallo, vielen dank für deine Hilfe. Das wird mir schon etwas weiterhelfen.
Thomas: Derin Freund ist die Befehlsreferenz im AVR-Studio, dort werden die Befehle, die du im Datenblatt in der Auflistung findest, recht ausführlich erklärt.
Hallo, was sowas gibts direkt im AVR-Studio? Ich habe immer das Instruction Set Datenblatt geöffnet. Wo soll das genau sein?
Oder zum Schmökern: Help, AVR tools user guide, AVR assembler Da findest du auch die Erklärung der Direktiven... Ist aber eigentlich traurig, dass du noch nicht soweit vorgedrungen bist... ...HanneS...
nochmal kurz zu dem Thema. bei einem ATTiny26 wir am Anfang ja der Stackpointer initialisiert. init: ;Stackpointer initialisieren ldi temp, RAMEND out SP, temp RAMEND steht in der tn26def.inc mit dem Wert $DF drin. Da der ATTiny26 ja 128Byte SRAM hat sollte ja DF für 128 stehen mein Win-Taschenrechner macht komischerweise dezimal 223 drauß. wäre es hier möglich statt RAMEND($DF) nur 112 zu übergeben somit hätte ich doch 16Bytes die nicht durch den Stack verwendet werden können und dadurch einen abgesicherten Bereich darstellen, da ich 100% sicherstellen will das diese Stellen nicht überschrieben werden auch wenn mal für eine Interruptroutine nicht gepopt und gepusht wurde.
> RAMEND steht in der tn26def.inc mit dem Wert $DF drin. Da der > ATTiny26 ja 128Byte SRAM hat sollte ja DF für 128 stehen Nein. Vor dem RAM kommen noch die ganzen Register. Steht alles im Datenblatt: "The lower 224 Data Memory locations address the Register File, the I/O Memory and the internal data SRAM. The first 96 locations address the Register File and I/O Memory, and the next 128 locations address the internal data SRAM." > mein Win-Taschenrechner macht komischerweise dezimal 223 drauß. Klar. 13 * 16 + 15 = 223 > wäre es hier möglich statt RAMEND($DF) nur 112 zu übergeben Dann hättest du aber nur 16 bytes für den Stack übrig, da das RAM erst an Adresse 96 anfängt. > somit hätte ich doch 16Bytes die nicht durch den Stack verwendet > werden können und dadurch einen abgesicherten Bereich darstellen, > da ich 100% sicherstellen will das diese Stellen nicht > überschrieben werden auch wenn mal für eine Interruptroutine nicht > gepopt und gepusht wurde. Dir ist aber schon klar, daß dein Programm dann trotzdem nicht funktionieren wird? Schließlich hast du damit auch nicht mehr Platz für den Stack und überschreibst dann statt deiner Variablen dann halt die I/O-Register, angefangen mit den Flags und (viel spaßiger) dem Stack Pointer.
Hallo, nach deiner Erklärung müsste ich einfach statt 223 207 als RAMEND setzen so das die letzen 16Bytes des RAMs wegfallen un das sollte den Programmablauf, zudem der sehr einfach gestrickt ist nicht stören.
Nicht als RAMEND, aber als Wert für SPL. Das Ende des RAM verschiebt sich ja nicht. Ich wage nur zu bezweifeln, daß das für die Robustheit deines Programms wirklich was bringt, da: a) wie gesagt, der Stack pointer eins der ersten Register ist, die überschrieben werden, und dann zeigt der nachher sonstwo hin (z.B. auf deine "geschützten" Variablen), und b) wenn du mal ein push vergisst oder ein pop zuviel hast, läuft der Stack Pointer auch munter nach oben, in den Bereich, für den du eigentlich "100% sicherstellen" wolltest, daß er nie überschrieben wird, und c) weil es eh Wurscht ist, was im RAM steht, wenn dein Programm amokläuft, einfriert oder andere typische Verhaltensmuster an den Tag legt, die durch ungleiches push/pop so autfreten können.
Hallo, der Tiny26 kennt ja kein SPL und SPH sondern nur SP und damit stelle ich doch den Bereich ein welcher für den Stackpointer zur Verfügung steht. Ein Stapelüberlauf wäre natürlich umbedingt zu vermeiden. Aber das weglassen der push/pop Befehlen am Anfang/Ende einer Interruptroutine würde hier überhaupt keine Probleme verursachen, weil hiervon doch nur Register betroffen wären. Pop und Push war jetzt vielleicht ein blödes Beispiel. Aber ich müsste halt ein paar Sachen ablegen können und möchte dazu nciht das EEPROM nutzen, weil es erstens sehr lange dauert und nach einer gewissen Anzahl von Schreibzugriffen hinüber gehen wird.
Im Prinzip ist das machbar. Es schützt dich aber nicht vor Programmierfehlern (Stack-über/unterlauf). Trotzdem solltest du dir mal den Daten-Adressraum genauer ansehen, SRAM beginnt nämlich (wie oben schon gesagt) nicht bei $00 sondern erst hinter dem I/O-Bereich. Und das ist je nach Controller bei $60 oder $100. Vor dem SRAM kommen also die 32 Register und die 64 I/O-Adressen und evtl. noch die Extended-I/O-Adressen. Die Adressbereiche werden aber in den Datenblättern anschaulich erklärt (Klötzchengrafik). ...
> der Tiny26 kennt ja kein SPL und SPH sondern nur SP und damit Ja, ist aber im Prinzip das gleiche. > stelle ich doch den Bereich ein welcher für den Stackpointer zur > Verfügung steht. Du stellst damit den initialen Wert für den Stackpointer ein. Einen Bereich legst du damit nicht fest. Bei jedem push wird der Stackpointer um eins verringert, bei jedem pop um eins erhöht. Wenn du also irgendwo ein pop hast, zu dem kein push existiert, läuft dein Stackpointer munter nach oben, Richtung RAMEND, und deine Variablen werden überschrieben. > Ein Stapelüberlauf wäre natürlich umbedingt zu vermeiden. Genau. Wenn dir das klar ist, wozu willst du dann den Stackpointer auf 16 byte vor RAMEND initialisieren? Das hilft überhapt nicht gegen einen Überlauf. > Pop und Push war jetzt vielleicht ein blödes Beispiel. Aber ich > müsste halt ein paar Sachen ablegen können und möchte dazu nciht > das EEPROM nutzen, weil es erstens sehr lange dauert und nach > einer gewissen Anzahl von Schreibzugriffen hinüber gehen wird. Ja, und wo ist nun das Problem? Dafür legst du einfach Variablen an, und zwar am Anfang vom RAM.
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.