Hallo Zusammen Ich habe eine Endlosschleife als Hauptprogramm, in dem mache ich Berechnungen mit Multiplikation und Division. Nun habe ich noch zwei Interrupts (Kommunikation per i2c), in der dazugehörigen ISR benötige ich die Register r17, r30, r31, diese werden mit PUSH/POP gesichert. Nun habe ich folgendes Problem: in dem Beispiel sollte das Resultat der Berechnung immer 200 ergeben, manchmal ist es aber 255 oder 528, je nach dem ob ein interrupt dazwischen greift. ich vermute da ein Problem mit den Registern (ISR <-> Hauptprogramm) Oder liegt der fehler wo anders ??
Michael L. schrieb: > Interrupts (Kommunikation per i2c), in der dazugehörigen ISR benötige > ich die Register r17, r30, r31, diese werden mit PUSH/POP gesichert. SREG nicht gepushed/gepoped
Also habe mal versucht das SREG zu sichern, der fehler besteht aber weiterhin. ISR: $asm Push r16 in r16, sreg .... out sreg, r16 pop r16 $end asm return gibt es noch andere Register die man Sichern muss ?
Ok, noch ein Nachtrag: R16, wird nur im Hauptprogramm verwendet, daher zuerst PUSH r16, dann das SREG in r16 ablegen, nun der code der ISR, und das ganze wieder zurück. r16 wird in der ISR sonst nicht verwendet. Sollte eigentlich in Ordnung sein, oder ?
Michael L. schrieb: > Sollte eigentlich in Ordnung sein, oder ? Denke ich auch. Im Header ist HWSTACK, SWSTACK, FRAMESIZE nicht angegeben. Die IDE defaultwerte könnten zu klein sein?
Die default werte sind: HW: 32 SW: 8 Framsize: 24 Ich muss zugeben, dass ich mich mit der Stack und Frame grösse zu wenig bis gar nicht auskenne :-(
Michael L. schrieb: > Ich muss zugeben, dass ich mich mit der Stack und Frame grösse zu wenig > bis gar nicht auskenne :-( HW: 32 Hardware-Stack, Rücksprungadressen, Registersicherung SW: 8 Software-Stack, Parameterübergabe für Funktionen Framsize: 24 funktionsinterne Variablen bei Aufruf von Funktionen ...
Frame und Stackwerte scheinen mir hier unkritisch. Hier was in deutsch dazu: http://halvar.at/elektronik/kleiner_bascom_avr_kurs/speicher_hwstack_swstack_frame/ In der I2c_read_write-ISR gibt es einen Sprung nach Speichern: Speichern: ist aber kein $asm. Keine Ahnung, was hier passieren könnte bzw was BASCOM daraus macht. Auch die Overlay declarationen versteh ich nicht. Kenn das so, das eine erste größte Variable "normal" deklariert wird und die folgenden dann darüber gelegt werden. Hab nicht nachvollzogen ob das bei dir OK ist. Sorry, war auch zu lustlos mich durch den asm code zu quälen :(
Das ganze ist ein Temperatursensor der als i2c Slave funktioniert. Der Slave verhält sich wie ein Eeprom. Das Datenregister Array ist sozusagen der Speicher, in dem der Messwert, Slave Adresse, Name des Messwerts, usw. enthalten ist. Der Master kann dieses Speicher Array auslesen, aber auch darein schreiben, um beispielsweise den Namen zu ändern, oder die Slave Adresse zu editieren. Damit die änderungen dauerhaft im uC Eeprom abgelegt werden, muss der Master die Subadresse &h9F aufrufen, der Slave springt nun zu "Speichern:" und legt das Speicher Array im eeprom ab und macht danach ein RESET (goto &H00). Im Normalen Messbetrieb, wie es momentan der fall ist, Springt der uC aber nie zu "Speichern:" Mit Overlay kann man einer Variablen eine absolute Adresse im SRAM vergeben. Nun ist es einfacher mit ASM auf die Variable zu zugreifen. Ich habe allen Variablen manuel eine Adresse vergeben, damit es keine überschneidungen geben sollte.
So habe nun noch was anderes ausprobiert: im Hauptprogramm die berechnung weggelasen, und stattdessen einen fixen wert zugeteilt (530). ohne sichern des SREG in der I2c_read_write-ISR, funktioniert alles einwandfrei. Sobald ich das SREG sichern will fangen die Probleme an. Der Codeausschnitt: I2c_read_write: $asm push r16 push r17 push r30 push r31 in r16, sreg ..... pop r31 pop r30 pop r17 sbi Usisr, 6 'Counteroverflow reset Out Sreg , R16 pop r16 $end Asm Return
Hallo, die "Overlay-Variablen" sind bei BASCOM nicht mehr notwendig. BASCOM bietet eine einfache Option, auf deklarierte Byte-Variablen in Assembler zuzugreifen. Der Compiler übernimmt dann die Verwaltung der Absolut-Positionen im Speicher. Beispiel: >> Dim TestVar as Byte >> $asm >> ... >> LDS R16, {TestVar} >> ... >> STS {TestVar}, R16 >> $end asm Was noch auffällig ist: SO wird SREG nicht korrekt gesichert: > push r16 > push r17 > push r30 > push r31 > in r16, sreg > ... Normal ist so: (zu Beginn der Assembler-ISR) push r16 in r16, sreg push r16 push r17 push r30 push r31 ... und zurück: (am Ende) ... pop r31 pop r30 pop r17 pop r16 out sreg, r16 pop r16 Nur so ist sichergestellt, dass sich ALLE Register nach Verlassen der ISR im alten Zustand befinden.
Korrektur:
> die "Overlay-Variablen" sind bei BASCOM nicht mehr notwendig.
Bevor es Beschwerden hagelt: hier ist nur die "Overlay"-Nutzung für
Variablen-Übergabe BASCOM <> Assembler gemeint. Für andere Anwendungen
sind sie vielfach eine praktische Sache ...
Weitere Versuche: habe die beiden befehle in/out SREG auskommentiert, und nur das push/pop r16 stehen gelassen, und die Probleme sind trotzdem da ! Lasse ich Push/pop r16 ebenfalls weg, funktionierts ! Sieht also aus, als ob trotzdem irgend ein Stack zu klein ist ?!?
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.