Grundlegende Frage SRAM

Gast #3443593
Lesenswert?

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
Gast #3443612
Lesenswert?

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
Gast #3444260
Lesenswert?

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.
Gast #3444286
Lesenswert?

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
Gast #3444994
Lesenswert?

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,?
Gast #3445058
Lesenswert?

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
Gast #3445067
Lesenswert?

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
Gast #3445300
Lesenswert?

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
#3445340
Lesenswert?

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.
#3445705
Lesenswert?

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.
1
.DSEG            ;Reserve jeweils 1 Byte im SRAM
2
Ergebniss1l:    .byte 1
3
Ergebniss1h:    .byte 1
4
Ergebniss2l:    .byte 1
5
Ergebniss2h:    .byte 1
6
Aufloesung1l:    .byte 1
7
Aufloesung1h:    .byte 1
8

9
.CSEG
10
.ORG  0x00
11
rjmp reset
12

13
reset:
14
ldi temp, high(RAMEND)    ;Stackpointer initialisieren
15
out SPH,  temp
16
ldi temp, low (RAMEND)
17
out SPL,  temp
18

19
ldi temp,  low(3600)    ;Auflösung = 0,1°
20
ldi temp2, high(3600)
21
sts Aufloesung1l, temp
22
sts Aufloesung1h, temp2
Gast #3450241
Lesenswert?

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
Angehängte Dateien:
#3451034
Lesenswert?

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...
Gast #3451821
Lesenswert?

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.
Angehängte Dateien:
Gast #3451938
Lesenswert?

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
Gast #3451998
Lesenswert?

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.
Gast #3452677
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren