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
Amok laufende Pointer könnte man noch ergänzen. Wer weiß, was "..." alles bedeutet.
Hi >Amok laufende Pointer könnte man noch ergänzen. Wer weiß, was "..." >alles bedeutet. Es geht um Assembler. 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.
.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
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.
>oder Problem mit STACK Pointer?)
Initialisierst Du den irgendwo?
Der sollte gleich am Anfang des Programms auf RAMEND gesetzt werden.
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 |
Hast du es mal durchsimuliert, gerade die Interuptsaufrufe und beobachte dabei das dseg.
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
Fehler kann durch Interrupts ja eigentlich nur verursacht werden wenn ich die Register nicht sichern würde mit push und pop?
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
Ja ganz Blöd. Sorry. Hab jez erst bemerkt was ich da für einen Blödsinn verzapft hab.
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.
twitest wird sonst nirgends verwendet. Das passt also. Wie gesagt Fehler gefunden. Ganz dumm. Sorry
1 | ldi temp1,0b00000000 ;normal operation (overflow) |
2 | sts TCCR1A,temp1 |
speicherst du die Einstellungen zusätzlich im RAM oder funktioniert hier statt out auch sts?
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
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.