Fehler in Macro

wer

Neues Mitglied
02. Juli 2012
485
0
0
Sprachen
  1. Assembler
Liebe Profis!

Ich habe einen Fehler in dem folgenden Macro:
Code:
.EQU	F_CPU= 19660800
.EQU	F_INT	= F_CPU/256

.MACRO STA 
	ldi	R6,  low(@0)
        ldi	R7, high(@0)
	ldi	R8,  low(@1)
        ldi	R9, high(@1)
.ENDMACRO

#define sta(s) STA	(s*F_INT), (s*F_INT)/65536

Aufruf z.B.

Code:
	sta	(0.015)

Wie debuggt man sowas?
 
LDI geht nur bei den oberen 16 Rechenregistern...
(gilt für alle Immediate-Mnemonics, wenn ich mich nicht irre)
 
LDI geht nur bei den oberen 16 Rechenregistern...
(gilt für alle Immediate-Mnemonics, wenn ich mich nicht irre)
Manchmal sucht man halt vollkommen in der falschen Ecke!

Trotzdem! Wie könnte man denn die beiden Parameter @0 und @1 des macros anzeigen lassen?
 
...in der falschen Ecke!...
Normalerweise müßte er Dir'n "invalid Register error" um die Ohren knallen, sogar 4. Eventuell auch noch irgend'n Fehler dort, wo Du das Macro aufrufst...
.
...Wie könnte man denn die beiden Parameter @0 und @1 des macros anzeigen lassen?...
Wie bzw wo meinst Du?
In Deinem Code sind das ja letztendlich Präprozessor-Konstanten, die entsprechend in die Opcodes miteingerechnet werden. Wenn der AVR die am Ende ausgeben soll (UART, SPI, whatever), kannst Du das in Deinem Beispiel halt nach dem Makroaufruf tun - also die 4 Register rausblasen...
Oder willst Du 'n entsprechende Meldung bei der Compilierung ausgeben lassen?

das geht zwar mit den direktiven .message, .error und .warning, allerdings akzeptieren die keine Präprozessor-Variablen, sondern nur Strings.
verwendest Du hingegen die #-Direktiven, kannst Du das zwar scheinbar ausgeben, allerdings wird das nicht wirklich berechnet.

Such mal, das hatten wir hier schon irgendwo mal versucht...
 
Such mal, das hatten wir hier schon irgendwo mal versucht...

Wenn ich mich richtig erinner waren das wir 2, allerdings per PM.
Es wurde nicht der berechnete Wert sondern die Fornel selbst ausgegeben.

Wie man die Werte ausgeben kann kA, mehr als schon geschrieben fällt mir auch nicht ein. Außer Simulator/debugWire/JTag und passend breakpoints setzen
 
Beim #define wurde irgendwie die Definition ausgegeben, aber da war noch irgend'ne Unregelmäßigkeit mit drin...

Im Simulator könnte man das mit Quickwatch (shift+F9 oder so) machen, mit 'ner Formel über die Register, aber das ist genauso umständlich...

Warum überhaupt 'ne Präprozessorfunktion, die'n Makro aufruft? Kannst Doch genausogut alles direkt in's Makro schreiben...

@Thomas: dann wird er's hier wohl nicht finden... jetzt erinner ich mich wieder... wollte da irgendwas mit der Baudrate und dem Fehler ausgeben lassen.
Blöd eigentlich, daß es keinen Weg zu geben scheint, derlei Präprozessor-Konstanten bei der Assemblierung nicht mitausgeben zu lassen. Die werden ja genau da zur Berechnung der Opcodes bzw Adressen verwendet...
 
Warum überhaupt 'ne Präprozessorfunktion, die'n Makro aufruft? Kannst Doch genausogut alles direkt in's Makro schreiben...
Ich hatte ja einen Fehler! Und die Ursache dieses Fehlers hatte ich zunächst darin vermutet, daß der übergebene Parameter deutlich größer als 16 Bit sein kann. Also habe ich mir den Wert in zwei 16 Bit Werte zerlegt, brauchte dann aber das #define um eben doch nur einmal die Zeit einzugeben.

Jetzt wo ich weiß, wo der Fehler liegt brauche ich das natürlich nicht mehr.

Aber die Frage zielte ja weniger auf das finden des konkreten Fehlers, sondern auf eine Möglichkeit solche Konstrukte zu debuggen. Könnt Ihr Eure (Teil)lösung hier noch mal posten?
 
Ich glaube das war dieser Code (ohne Gewähr):
Code:
;
; Constants
;

	.EQU F_CPU = 18432000	; System clock in Hz. Change if required
	.EQU BAUD = 288000	; Baudrate to use. Change if required.

;
; Baudrate calculation
;

	.EQU UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1)
	.EQU BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1)))
	.EQU BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)
	.IF ((BAUD_ERROR>10) || (BAUD_ERROR<-10))
		.ERROR "Baudrate error larger than 1%! Change either BAUD or F_CPU."
	.ENDIF
 
Ok! Und da wäre dann also z.B. das Problem, wie man sich z.B. den Wert von BAUD_ERROR anzeigen läßt.
 
Genau das ist das Problem gewesen, weil ein
.ERROR BAUD_ERROR
gibt leider nicht den berechneten Wert zurück, sondern die Formel. Also "((BAUD_REAL*1000)/BAUD-1000)"

Eine Lösung für das Problem kenne ich nicht, hatten wir damals auch nicht gefunden.
 
... weniger auf das finden des konkreten Fehlers, sondern auf eine Möglichkeit solche Konstrukte zu debuggen. Könnt Ihr Eure (Teil)lösung hier noch mal posten?
Verstehe ich nicht... Du versuchst das einfach zu assemblieren, und der Assembler haut Dir dann irgendwann 'ne Fehlermeldung vor die Nase (hier eben das "Invalid Register" - Du hast also ein Register verwendet, daß für diesen Befehl nicht zugelassen ist. Also wirfst Du einen Blick in's Instruction Set, und findest, daß LDI nur auf die oberen 16 Rechenregister paßt. Kannst ja mal mit IN/OUT auf ein I/O-Register größer als 0x3F zugreifen)
Vor hinter der Fehlermeldung steht sogar, in welcher Zeile der Fehler eingetreten ist - und wenn Dir das nicht reicht, fokussiert ein Doppelklick darauf direkt die betreffende Zeile...

Der Präprozessor verkraftet mehr als 16bit-Zahlen (Deine F_CPU sind ja schon 25bit).
Achtung low() liefert das letzte Byte, high liefert aber nicht das erste, sondern das vorletzte. Bei 'ner 16bit-Zahl paßt das erstmal, bei größeren und insbesondere bei negativen allerdings...

statt low() und high() gibt es auch byte1()..byte4(), die dann das jeweilige Byte (von hinten) liefern

@Thomas: ich hatte AFAIR noch irgendwie das UX2-Bit mit drinn, aber ansonsten war's so ähnlich...
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)