Hallo zusammen,
habe folgendes Problem, ich möchte in der ISR für den timer0 overflow
zwei sich im SRAM befindende 16-Bit counter inkrementieren. Das
funktioniert auch soweit sofern ich nur einen counter benutze. Lasse ich
jedoch beide counter laufen, funktioniert das ganze nicht mehr,
wahrscheinlich überschreiben sich die beiden gegenseitig oder so.
Hier mal der relevante Code:
"Kann zwar keinen Fehler bezüglich des Hochzählens erkennen, aber am
Ende
der ISR sollte out SREG, r0 stehen und nicht in SREG, r0"
Das habe ich ausprobiert, aber funtkioniert leider trotzdem nicht.
"Hast Du mal nachgerechnet ob der Code abgearbeitet werden kann,
bevor das nächst mal der Int. vom Timer auftritt?"
Das sollte eigentlich passen, der overflow tritt nur jede milli Sekunde
auf.
Aber generell sollte das mit der Adressierung aber hinhauen, oder? Wie
gesagt sofern ich nur einen inkrementiere funktioniert alles,
inkrementiere ich beide geht es halt nicht...
Habt ihr vielleicht noch eine Idee für einen workaround, möchte ungern
zwei arbeitsregister verschwenden nur für einen Zähler?
Maik wrote:
> "Kann zwar keinen Fehler bezüglich des Hochzählens erkennen, aber am> Ende> der ISR sollte out SREG, r0 stehen und nicht in SREG, r0">> Das habe ich ausprobiert, aber funtkioniert leider trotzdem nicht.
Was hast Du denn fürn komischen Assembler?
Das "in SREG, r0" erzeugt mit dem AVR-Assembler 2 die Fehlermeldung:
t13.asm(66): error: Invalid register
Peter
Hallo Peter Dannegger,
"in SREG, r0"
geht bei mir poblemlos durch, ohne Fehler oder Warnungen.
Ist zwar ungewöhnlich SREG in R0 zusichern (würde es auf dem
Stack tun) aber es sollte gehen.
AVR-Studio 4.13
Klaus
Zur Info, das ganze läuft auf einem ATmega16 bei 16 MHz...
"wenn Du nichts über den Vorteiler schreibst wirds schwierig."
Ich dachte, dass wäre nicht relevant, der Vorteiler wird im Präprozessor
vom Compiler berechnet, was aber definitiv funktioniert, benutze den
Code dafür auch schon länger und es gab nie Probleme.
Zum testen habe ich aber die Anweisung um die LED ein/aus zu schalten
hinter den ersten counter gehängt der diese dann nach 1000 Zählvorgängen
(als 1000x1ms=1Sekunde) ausführt.
Der Code ist eine Datei die ich im Hauptprogramm includiere
"Wo ist denn Dein Datensegment plaziert?"
Wird das nicht automatisch vom compiler organisiert, der beim SRAM
anfang beginnt und nacheinander dort die Bereiche für die definierten
Variablen reserviert???
In anderen includierten Dateien benutze ich auch auf diese Weise
Variablen die alle funktionieren.
In diesem Codeabschnitt benutze ich allerdings das einzige Mal
reservierte Bereiche mit mehr als 8-Bit, kann es vielleicht daran
liegen?
Hatte das vorher auch schonmal alles über .DB und .DW organisiert, hat
aber auch nicht geklappt.
"Was hast Du denn fürn komischen Assembler?"
Ich benutze AVRStudio 4 mit dem entsprechenden Assembler.
Das mit dem "in" ist mir beim abschreiben des Codeschnippsels für diesen
Beitrag passiert, im Code selber benutze ich "out".
"Ist zwar ungewöhnlich SREG in R0 zusichern"
Ach das klappte bisher einwandfrei... ist ja eines der "limitierten"
Register, die man leicht entbehren kann.
@ Klaus (Gast)
>"in SREG, r0">geht bei mir poblemlos durch, ohne Fehler oder Warnungen.
???
Kann gar nicht, weil vollkommen falsch. IN lädt I/O Register in CPU
Register, und das erste Argument muss ein CPU Register sein.
>Ist zwar ungewöhnlich SREG in R0 zusichern
Das würde man mit
Also das mit "in" und "out" funktioniert definitiv, sollte nicht das
Problem sein. Wie gesagt im ersten Beitrag war es wirklich ein
Abschreibefehler!!!
in und out sind wie folgt definiert:
in Rd, SFR ==> lade Rd mit SFR Register
out SFR, Rd ==> lade SFR mit Rd
Habe das, was Peter Danegger geschrieben hat mit .org SRAM_START
ausprobiert, dabei bekomme ich immer einen Fehler beim compilieren:
error: Overlap in .dseg: addr=0x60 conflicts with 0x60:0x73
und das für alle darauf folgenden Speicherreservierungen.
@ Falk
hast Du gelesen?
push r0
in r0, SREG ; am Anfang der ISR
>Kann gar nicht, weil vollkommen falsch. IN lädt I/O Register in CPU>Register, und das erste Argument muss ein CPU Register sein.
ja klar SREG ist eine Ram-Zelle
@ Maik
>Der Code ist eine Datei die ich im Hauptprogramm includiere
was macht der µC da in der Zwischenzeit?
Klaus
@ Maik (Gast)
>Also das mit "in" und "out" funktioniert definitiv, sollte nicht das>Problem sein. Wie gesagt im ersten Beitrag war es wirklich ein>Abschreibefehler!!!
Abschreibfehler? Wer Quelltexte ABSCHREIBT sollte sich ne Packung
Ohrfeigen abholen. So ein Blödsinn zu machen ist fast strafbar.
Quelltexte werden sinnvollerweise direkt als Anhang gepostet. Dann gibt
auch keine Abschreibfehler. Ich glaub ich steh im Wald.
MFG
Falk
push r0
in r0, SREG
.
.
.
in SREG, r0
pop r0
push r0
in r0, SREG
.
.
.
out SREG, r0
pop r0
ist doch das gleiche. Der Inhalt von SREG steht während der Punkte
in R0. Es ist Wurst, ob ich mir den Wert von SReg über "in" aus R0
zurück hohle, oder ihn über "out" bewußt dahin zurück schreibe.
Klaus
@ Klaus (Gast)
>push r0> in r0, SREG
.
.
.
> in SREG, r0
GEHT NICHT!
Siehe mein Posting
Beitrag "Re: 2x 16-Bit counter im SRAM funktioniert nicht (AVR, ASM)"
Dort muss stehen
out SREG, r0
Der Abschreibfehler, schauder!
> in R0. Es ist Wurst, ob ich mir den Wert von SReg über "in" aus R0> zurück hohle, oder ihn über "out" bewußt dahin zurück schreibe.
Nöö, du kannst mit IN keinen Wert IN SREG schreiben, nur AUS SREG lesen.
MFG
Falk
"Abschreibfehler? Wer Quelltexte ABSCHREIBT sollte sich ne Packung
Ohrfeigen abholen. So ein Blödsinn zu machen ist fast strafbar."
Danke für die klaren Worte, sowas mag ich :-)
Ich kann dir diesen Blödsinn aber erklären, ich habe den Code
ursprünglich mit Kopieren/Einfügen in den Beitrag eingefügt, allerdings
kann der Beitragseditor anscheinend nicht so gut mit Tabulatoren umgehen
und es gab Darstellungsfehler in der Vorschau, vielleicht auch da
AVRStudio stadardmäßig eine Tabulatorbreite von 4Zeichen und nicht wie
üblich 8 Zeichen verwendet (damit hatte ich schon öfters Ärger, habs
aber bewußt nicht umgestellt).
Also habe ich die eingefügten Zeilen per Hand bearbeitet und den zweiten
counter habe ich dann aus dem bereits editierten Stück kopiert und
geändert, ebenso bin ich auch mit dem zurückschreiben der Register
verfahren und habe diese aus dem Anfang des editierten Beitrags
kopiert... dabei habe ich dann zwar die Reihenfolge der Operanden
verändert allerdings nicht das "in" in "out" geändert. (Erklärt das
diesen, zugegebenen, Schwachsinn?)
Aber weiter mit meinem Problem, dass Hauptprogramm empfängt per
Interrupt auch noch RC5 codes, wertet sie aus und sendet sie über die
UART.
In diesen Routinen, die auch im Hauptprogramm includiert werden, benutze
ich ebenfalls den SRAM und diese stören sich nicht gegenseitig, deshalb
gehe mich mal davon aus, dass der Speicher generell schon richtig vom
compiler organisiert wird (die Routinen funktionieren auch einwandfrei,
sogar mit in, out und R0 in den ISRs).
Ich nehme an, dass es eher was mit den erstmalig verwendeten 2 Byte
reservierungen zu tun hat, bin aber nach wie vor ratlos, was ich noch
verändern könnte.
Wie sieht das aus, es ist doch so, dass, solange eine interrupt
gehändelt werden die anderen gesperrt werden, bis das handling
abgeschlossen ist?
ist komisches Zeug warum mein µC das mit 16MHz das nicht schafft!
>Der Code ist eine Datei die ich im Hauptprogramm includiere
Kommentiere doch bitte mal die restlichen ISRs aus!
Du wirst sehen das (nahzu 100%) Dein Code-Snip rennt!
Du hast zu 100% Warhscheinlichkeit ein Zeit-Problem,
auf dem µC!
Klaus
Was schafft denn dein µC mit 16MHz nicht, 16 MHz ist doch wirklich schon
"atemberaubend"? :-)
Also, hab das gemacht, was du mir geraten hast und wirklich ALLES
weggelassen, das Programm macht jetzt nichts mehr, ausser in einer
Endlosschleife im Hauptprogramm zu laufen und bei einem Timerinterrupt
den geposteten Code (abgesehen von dem zweimal "in")auszuführen.
Wie bereits vorher vermutet kann es am restlichen Programm nicht liegen
(es ist ja nunmehr nicht vorhanden).
Danke erstmal für die zahlreichen vorangegangenen Posts!
Habt ihr sonst noch Ideen... schaut euch doch bitte nochmal mein
Codeschnippsel an irgendwo muss sich der Hund doch in den Schwanz
beißen???
Das ist völliger Unsinn.
Die Macros LOW und HIGH haben nur zum Laden eines Pointers Sinn, d.h.
bei Verwendung des Befehls "LDI".
"LDS" benötigt immer die ganze 16Bit-Adresse, d.h. Deine Zugriffe gehen
in den Wald.
Peter
Danke Peter Dannegger, das hätte ich wahrscheinlich erstmal weiter
übersehen...
Und wie mache ich das dann jetzt am besten, lade ich die Adresse des
Speicherbereichs in den Pointer und lese/schreibe die Werte dann aus,
oder lade ich mittels "lds XL, counter1" den kompletten 16-Bit Inhalt
und speichere ihn mit "sts XL, counter1"?
EUREKA er hats... Genau das wars!
Du bist einfach der Beste, vielen vielen DANK!!!
Da wäre ich so schnell nicht drauf gekommen, wieder was dazu gelernt :-)