Hallo,
Grundlegende Frage zum SRAM von einem AT90CAN32.
Brauche einige Speicherregister die ich im Programm oft ein- und
auslese.
Ich definiere die Register wie folgt im SRAM:
*******************************************************************
.include <can32def.inc>
.def temp = r21
.dseg
Beispiel_register1: .Byte 1 ;Register definieren
Beispiel_register2: .Byte 1
.cseg
.org 0x0000
rjmp init
.
.
.
.
********************************************************************
Und beschreiben bzw. auslesen mache ich wie folgt:
lds temp,Beispiel_register1
.
.
.
sts Beispiel_register1,temp
Ist das bis dahin alles richtig so ?
Kann es passieren das der Prozessor auf Grund von falsch gesetzten Fuse
bits oder falscher Registerdefinition (falls die oben falsch sein
sollte) mir sporadisch Unsinn in von mir definierte SRAM Register
schreibt bzw. ich unsinn auslese? (oder Problem mit STACK Pointer?)
Habe nämlich einen Fehler im Programm der ganz sporadisch auftretet.
Manchmal nach 2 Stunden z.B.. und wollte sicher gehn dass ich da keinen
Fehler beim auslesen oder schreiben vom SRAM mache.
Für Hilfe bin ich dankbar!
LG
Hi
>Ist das bis dahin alles richtig so ?
Ja.
>Kann es passieren das der Prozessor auf Grund von falsch gesetzten Fuse>bits
Die Fuse-Bits haben nichts mit dem RAM zu tun.
>oder falscher Registerdefinition (falls die oben falsch sein>sollte)
Das ist richtig so.
>(oder Problem mit STACK Pointer?)
Der AT90CAN32 hat 2k Ram. Den musst du erst mal mit dem Stack voll
bekommen. Prinzipiell ist das natürlich möglich: Rekursive Aufrufe, ein
einsames 'PUSH' das regelmäßig ohne das zugehörige 'POP' aufgerufen
wird, ... .
MfG Spess
spess53 schrieb:>>Amok laufende Pointer könnte man noch ergänzen. Wer weiß, was "...">>alles bedeutet.>> Es geht um Assembler.
Als wenn es in Asm keine Pointer gäbe...
Natürlich kann in purem Asm ganz genau dieselbe Scheiße passieren, wie
in in Macro-Assemblern wie etwa C und auch in allen echten Hochsprachen,
solange sie nur Pointer und Pointer-Arithmetik prinzipiell ermöglichen.
Viele dieser potentiellen Probleme sind allerdings in Asm deutlich
einfacher zu erkennen, weil einem nicht der Syntax-Vorhang die Sicht auf
das Geschehen auf dem Spielfeld versperrt.
Hi
>Als wenn es in Asm keine Pointer gäbe...
Ist mir seit Anfang der 80er bereits bekannt.
>Viele dieser potentiellen Probleme sind allerdings in Asm deutlich>einfacher zu erkennen,...
Genau deshalb meine Bemerkung. Und die Frage des TO lässt mich stark
vermuten das Pointer hier nicht im Spiel sind. Deswegen muss man das
nicht unnötig verkomplizieren.
MfG Spess
Mikki Merten schrieb:> .dseg> .org SRAM_START ;1. SRAM Adresse nach I/O> Beispiel_register1: .Byte 1 ;Register definieren> Beispiel_register2: .Byte>> evtl. Zeile 2 Vergessen ? Sonst wird auf R0, R1 zugegriffen
Ist das so? Hab die zeile nicht drinnen.
SRAM_START ist wie definiert? Im includefile,?
Hi
>> evtl. Zeile 2 Vergessen ? Sonst wird auf R0, R1 zugegriffen>Ist das so? Hab die zeile nicht drinnen.>SRAM_START ist wie definiert? Im includefile,?
Selbstverständlich im Include File:
.equ SRAM_START = 0x0100
.equ SRAM_SIZE = 2048
.equ RAMEND = 0x08ff
Das .org SRAM_START kannst du dir auch sparen. Der Assembler ordnet die
Variablen automatisch nach .dseg ab RAM_START an.
MfG Spess
Hi
Nachtrag: Das stammt ja nicht von dir, sondern von Mikki.
@ Mikki Merten (mmerten)
Nach .dseg ist kein .org SRAM_START notwendig. genau so wenig wie ein
.org $0000 nach dem .cseg am Programmstart. Das macht der Assembler
selbst.
MfG Spess
Stimmt seit Vers. 2.xx wertet der Assembler SRAM_START selber aus. Das
war den 1.xx Versionen noch nicht der Fall. Dann bleibt wohl eher das
häufig
vergessene sichern und restaurieren des SREG in Interrupt-Routinen ;)
Hi
>Stimmt seit Vers. 2.xx wertet der Assembler SRAM_START selber aus. Das>war den 1.xx Versionen noch nicht der Fall.
Im 4er Studio sind beide Assembler enthalten. Bei beiden ist das .org
nicht notwendig.
MfG Spess
also ich hab hier noch 4er .lst files bei denen das nicht der Fall ist.
Da wurde immer 0 angenommen. War damals ein echter Stolperstein die
Unterschiede 0x60 (Classic AVR) oder 0x100 bzw. 0x200 bei den neueren
MEGA im Griff zu halten.
Wobei mit .dseg per Default bei SRAM_START zu beginnen, auch nicht
unbedingt
korrekt ist, zumindest aber dokumentiert das dies ab Vers. 1.75 der Fall
ist.
Thomas O. schrieb:> Benutzt du Interupts?
Ja benutze ich !
Denkst du da an eine mögliche fehlerquelle? Arbeitsregister sichere ich
mit push und pop. Hatte da nämlich schon mal einen Fehler.
ich mache das auch so wie du neben der Register die man am schnellsten
ansprechen kann lege ich bestimmte Sachen im SRAM ab um Sie jederzeit
wieder dort abholen zu können, wenn ich die Register anderweitig
verwenden will.
ich setzte meinen Programmstart auch immer auf 0x00 habe mir aber schon
gedacht das das der Assembler selber macht.
Thomas O. schrieb:> Hast du es mal durchsimuliert, gerade die Interuptsaufrufe und beobachte> dabei das dseg.
Wo kann ich das dseg beobachten?
Habe jetzt den Fehler auf eine Divisionsroutine eingegrenzt.. wenn ich
diese durch die gleiche Divisionsroutine nur mit anderen Register
ersetze (also statt call Division_32_32 ... call Division_32_32_X) und
nur bei der fehlerhaften Stelle aufrufe dann funktionierts.
Wenn ich dann aber überall wieder die gleiche (also mehrmals im
Programm) Divisionsroutine aufrufe funktionierts nicht mehr.
Jetzt frag ich mich natürlich wo der Fehler ist. Ganz verstehen tu ichs
nicht.
Kann es an der Divisionsroutine selber der Fehler sein weil sie zu oft
aufgerufen wird?
Divisionsroutine ist am Anhang. Vielleicht findet wer einen Fehler?
LG
Poste halt mal den komnpletten Code.
Leute wie c-Hater, deren Blick dann durch nichts getrübt ist, werden dir
dann sicher helfen den Fehler zu finden.
(Sorry, aber da musste jetzt mal sein)
oder wenn ein Interrupt nicht wieder korrekt beendet wird wird einfach
der nächste Befehl ausgeführt der nach der Interruptroutine steht. Wenn
das dann ein paar hundert mal passiert ist der SRAM bei den kleinen AVRs
dann voll.
Hab hier leider kein AVR-Studio auf dem Lappi, bei der Version 4 konnte
ich ein Fenster öffnen wo ich dann Data auswählen konnte, dann sah ich
genau wo was ins SRAM geschrieben oder gelesen wurde, schaute wie ein
kleines Fenster ala HEX Editor aus.
Starte mal das Programm im AVR-Studio, dann kannst du schritt für
Schritt das Programm abarbeiten oder mit Breakpoints Sachen
überspringen, die Eingangspins kannst du per Mausklick umschalten um
z.B. das Programm drauf reagieren zu lassen und sieht immer sehr schon
wohin das Programm abzweigt...
Hallo,
Bin jetzt mit der Fehlersuche weiter. Der Fehler dürfte im Interrupt
liegen. Ich verstehe leider nicht warum.
Im Anhang sende ich die Programmteile mit der timer1_interruptroutine
der timer1 initialisierung, der Berechnung2 wo der Fehler schlussendlich
auftritt nach der Division, und der Divisionsroutine selbst.
Entdeckt wer beim Interrupt einen Fehler?
Ich komm nicht mehr weiter und häng grad.
Divisionsroutine habe ich nicht selber geschrieben..
Die anderen Sachen( ich weiß sie könnten schöner programmiert
sein...mein Fehler).
Danke!
LG
PS: Das Fenster wo ich das SRAM überwachen kann hab ich im AVR Studio 4
leider nicht gefunden.
Hi
Mal ehrlich, du rufst die Divisionsroutine, in der keines der
verwendeten Register gesichert wird, im Mainloop und im Timerinterrupt
auf. Schon mal überlegt, was passiert, wenn der Timerinterrupt mitten in
der Division des Mainloops zuschlägt?
>PS: Das Fenster wo ich das SRAM überwachen kann hab ich im AVR Studio 4>leider nicht gefunden.
View->Memory. Dort 'Data' auswählen.
MfG Spess
Luke schrieb:> Bin jetzt mit der Fehlersuche weiter. Der Fehler dürfte im Interrupt> liegen. Ich verstehe leider nicht warum.> Entdeckt wer beim Interrupt einen Fehler?
Der Interupthandler enthält (wahrscheinlich) einen Fehler, der sofort
auffällt. Du benutzt twitest zum Retten der Flags ohne twitest zuvor
erstmal selber zu retten. Damit ist im Minumum erstmal der Inhalt von
twitest verloren.
Ob das wirklich ein Fehler ist, hängt davon ab, ob twitest auch noch
irgendwo anders im Code verwendet wird. Der symbolische Name weist
darauf hin, daß das wohl der Fall ist, im geposteten Teil des Codes ist
er aber nirgendwo weiter zu finden.
Hi
>speicherst du die Einstellungen zusätzlich im RAM oder ...
TCCR1A liegt im erweiterter IO-Bereich und ist nur mit sts ansprechbar.
>...funktioniert hier statt out auch sts?
STS funktioniert immer. Z.B. lädt ein 'sts 0,r16' das Register r0 mit
dem Inhalt von r16. Allerdings sind die Adressen der Register, die mit
in/out erreichbar sind, im inc-File an in/out angepasst. Also 0x20
kleiner als für sts/lds.
MfG Spess