Habe mir bei ATtiny84 mal den Stackpointerwert ausgeben lassen, bekomme 607 dezimal. Mein Programm hat eine Menge PUSH und POP und RCALL und RET drin, funktioniert ansonsten, obwohl ich 1. den Stackpointer zu initialisieren vergessen habe 2. der ATtiny84 laut Datenblatt nur 512 Byte RAM hat. Warum 607 und nicht 511?
Peter X. wrote: > Habe mir bei ATtiny84 mal den Stackpointerwert ausgeben lassen, bekomme > 607 dezimal. Dann steht er noch auf RAMEND... > > Mein Programm hat eine Menge PUSH und POP und RCALL und RET drin, > funktioniert ansonsten, obwohl ich > 1. den Stackpointer zu initialisieren vergessen habe Datenblatt Seite 11 Absatz 4.6.1 zeigt die Register SPL und SPH und zeigt auch als Startwert (Initial Value) RAMEND an. Man braucht den SP bei diesem AVR also nicht mehr per Hand initialisieren, das macht die Reset-Hardware bereits. > 2. der ATtiny84 laut Datenblatt nur 512 Byte RAM hat. Richtig. Und wo beginnt der SRAM? > > Warum 607 und nicht 511? 96 + 511 = 607 oder? ...
Der pointer ist natuerlich 16 bit SPL:SPH, wobei alle bit oberhalb 9 abgeschnitten werden.
3357 wrote: > Der pointer ist natuerlich 16 bit SPL:SPH, wobei alle bit oberhalb 9 > abgeschnitten werden. Kannst Du das bitte mal genauer erklären? ;-) ...
Hi >Datenblatt Seite 11 Absatz 4.6.1 zeigt die Register SPL und SPH und >zeigt auch als Startwert (Initial Value) RAMEND an. Man braucht den SP >bei diesem AVR also nicht mehr per Hand initialisieren, das macht die >Reset-Hardware bereits. Aber Vorsicht, das gilt nicht für alle AVRs. MfG Spess
spess53 wrote: > Hi > >>Datenblatt Seite 11 Absatz 4.6.1 zeigt die Register SPL und SPH und >>zeigt auch als Startwert (Initial Value) RAMEND an. Man braucht den SP >>bei diesem AVR also nicht mehr per Hand initialisieren, das macht die >>Reset-Hardware bereits. > > Aber Vorsicht, das gilt nicht für alle AVRs. Ich weiß, bei meinem letzten Tiny24-Projekt (vor einer Woche) wusste ich das auch noch nicht und habe den SP schön brav von Hand initialisiert. Ich bin auch erst durch Vielfraß' Frage auf die Idee gekommen, im Datenblatt nachzuschaun. ;-) > > MfG Spess Bit- & Bytebruch, Hannes
Hi @Hannes: Wenn man nicht mit jedem Byte geizen muss, ist das auch kein Beinbruch. MfG Spess
Habe mal was getestet: Lasse mir in einer Endlosschleife den Stackpointer ausgeben. Bei jedem Schleifendurchlauf wird der Stackpointer durch ein "POP" ohne dazugehöriges "PUSH" um 1 erhöht. Anzeige der Werte über Hyperterminal mit 115200 Baud. Witzigerweise stürzt das Programm erst ab, wenn der Stackpointer 1023 erreicht hat.
1 | Big_loop: |
2 | IN Zahl_l,SPL |
3 | IN Zahl_h,SPH |
4 | RCALL Zahl_ausgeben |
5 | POP ACC ;Nur zu Testzwecken!!!!!!!!!!!!!!!!!!! |
6 | |
7 | ldi ACC,13 ;CR |
8 | rcall RS232_putchar |
9 | ldi ACC,10 ;LF |
10 | rcall RS232_putchar |
11 | |
12 | ldi ACC,20 |
13 | rcall Delay |
14 | rjmp Big_loop |
Warum?
Hi Vielfrass... Der Stack wächst nach unten (zu kleineren Adressen). Sein Startwert ist RAMEND, also das Ende vom RAM. Probleme gibt es, wenn der Stackpointer auf so geringe Adressen zeigt, dass der Stack Variablen, I/O-Register oder gar CPU-Register überschreibt. Du kannst den Stackpointer zwar über das RAM-Ende hinaus erhöhen, dort ist aber kein RAM und sonst auch nix. Die Adressierung greift daher erst beim Überschreiten des gesamten adressierbaren Bereiches, also wenn der Wertebereich (durch Bitbreite des SPH:SPL bestimmt) überschritten ist und damit die oberen Bits wirkungslos sind und die unteren (wirksamen) Bits auf die CPU-Register zeigen. Du solltest Dir den verfügbaren Adressbereich nochmal genau ansehen, ehe Du weitere Experimente machst, ansonsten ziehst Du falsche Schlüsse. Experimente sind zwar eine feine Sache, doch ohne Verständnis der Zusammenhänge bringen sie nicht viel. Und Vieles lässt sich im Vorfeld durch das Lesen der Datenblätter ermitteln, z.B. auch die Organisation des Speichers und seiner Adressbereiche. ...
also ich habe solche Spielchen früher auch schon mal gemacht, und teilweise war da wirklich mehr Speicher da als angegeben. Speziell ging es um den 4414 und 8515, RAM und EEPROM. Das sah so aus, als ob der 4414 die Resteverwertung von teildefekten 8515 war, aber auch nicht durchgängig.
Mir scheint, dass jeder AVR-Typ ein Versuchskarnickel ist, bei dem irgendein Feature für zukünftigen Serien-Einsatz getestet wird. Ich bin allerdings noch nicht auf die Idee gekommen, nach Teilen zu suchen, die es laut Datenblatt gar nicht gibt... (Nein, ich bin kein wandelndes Datenblatt, aber ich betreibe das nur zum Hobby und kann mir die Zeit nehmen, Datenblätter zu lesen...) ...
Habe mir das Datenblatt des ATtiny84 eben noch mal angesehen. Der Bereich der 32 Register geht von 0x0000 bis 0x001F Die 64 IO-Register gehen von 0x0020 bis 0x005F Die 512 Byte das RAM's gehen von 0x0060 bis 0x025F 0x025F = 607 dezimal. Was zwischen 0x0260 und 0x03FF ist, habe ich im Datenblatt bisher noch nicht finden können. Habe mich nur gewundert, das mein Programm trotz mehrerer Unterprogramme, die selber wieder Unterprogramme aufrufen nicht abstürzt, wenn der Stackpointer auf Adressen oberhalb 0x025F zeigt. "Versuch macht klug"
Wobei ich persönlich das automatische Initialisieren des Stackpointers für einen witzlosen Gimmick halte. Ich käme niemals auf die Idee den Stackinit am Programmanfang weg zu lassen. Alleine schon wegen der Probleme, wenn das Programm mal auf einen anderen AVR portiert werden soll (der dann eben nicht automatisch initialisiert...). Auch initialisiere ich JEDEN Portpin auf definierte Werte, auch wenn lt. Datenblatt der Port nach einem Reset schon auf dem-und-dem Wert stehen soll. Gleiches gilt für mich für jede andere AVR-Peripherie. Irgendwie fühle ich mich sonst nicht richtig wohl. Jochen Müller
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.