Archiv verlassen und diese Seite im Standarddesign anzeigen : Inline Assembler - Variablenverwaltung / Warnungen
Hallo,
ich will meinem Compiler die Registerauswahl überlassen, dazu habe ich eine Variable (hilf) definiert(uint8_t hilf) und weißer der dann im folgenden im InlineAssembler einen Wert zu. Die Zuweisung muss nähmlich GENAU da erfolgen.
Mit der Zeit nerven aber die Warnungen(hilf is used uninzilized), wie kann ich dem Compiler sagen, dass ich die Warnungen nicht mehr sehen will, an der Stelle?
Oder wie kann ich dem Compiler sagen, dass eine C Funktion genau an einer bestimmten Stelle ausgeführt werden soll? (Anmerkung: Der Compiler verschiebt die Variablenzuweisung immer und dann kommt Mist raus... So könnte man auch das Problem lösen.)
Ich hoffe Ihr könnt mir helfen, das Wiki konnte es nämlich nicht.
Grüße
Michael
SprinterSB
08.07.2007, 12:37
Ohne deinen Code zu sehen und was du da treibst (oder versuchst zu treiben) ist schlecht Rat zu geben.
Eine C-Funktion (bzw. Anweisung) wird irgendwann ausgeführt, und zwar so, daß die Abhängigkeiten der Variablen berücksichtigt werden.
Evtl. fehlt irgendwo ein "volatile" wenn's auf die Reihenfolge ankommt, evtl muss ein Block/Funktionsaufruf atomar erfolgen.
Die Warnung in Inline Assembler kommt wohl daher, daß du eine nichtinitialisierte Variable als Input-Operand verwendest.
Hallo mein Code:
#define edelay3(tacktschritte){ \
int a=tacktschritte; \
uint8_t b=tacktschritte%3; \
{\
a=a/3; \
uint8_t register hilf; \
asm volatile( \
"ldi %1,%0\n" \
"edelay3_%=:\n" \
"dec %1\n" \
"BRNE edelay3_%=\n" \
: : "M" (a),"r" (hilf) ); \
hilf=0; \
}\
if(b==0){ \
asm(";"); \
} \
if(b==1){ \
asm("NOP\n"); \
} \
if(b==2){ \
asm("NOP\nNOP\n"); \
} \
if(b==3){ \
asm("NOP\nNOP\nNOP\n"); \
} \
}
Funktioniert eigentlich bis auf die Warnmeldung prächtig.
Ich würde gerne schreiben hilf=a, das problem ist aber, es wird bei Schleifen manchmal verschoben, dass hilf nicht neu geladen wird.
Voltaile schreibt das doch aber die Variable nur immer ins Ram?
Ich hoffe Du kannst mir helfen.
Der Main C Code:
#include <avr/io.h>
#include <edelay.h>
#define us_port PORTC
#define us_ddr DDRC
#define us_pin 0
// #if F_CPU==1000000
// #error "aa";
// #endif
void ultraschall_sendc(uint8_t burst){
uint8_t i;
us_ddr|=(1<<us_pin);
i=burst;
//hier wird hilf geladen
do{
//hier müsste hilf geladen werden
us_port|=(1<<us_pin);
//hier hilf modifiziert
edelay(((F_CPU/1000000)*15)-5);
us_port&=~(1<<us_pin);
edelay(((F_CPU/1000000)*15)-8);
i--;
}while(i!=0);
uint8_t l=20;
while(l!=0){
edelay(690);
l=l--;
}
us_ddr&=~(1<<us_pin);
}
int main(void){
while(1){
ultraschall_sendc(20);
}
return 0;
}
Grüße
SprinterSB
10.07.2007, 23:40
Zunächst mal folgendes: Auch wenn der Code so erzeigt wird, wie es sein soll, gibt es keine Garantie dafür, daß dies immer so ist!
elelay ist ja keine Funktion, sindern ein Makro, und so könnte zB b im Frame der Funktion angelegt werden, wenn die Funktion, die das Makro verwendet, komplex ist.
Zudem ist es sehr ungünstig, /3 und %3 zu berechnen, weil das teuer ist. wesentlich besser wäre hier die Verwendung einer Schleife, die 4 Zyklen braucht!
#define NOP asm volatile ("nop")
#define edelay3 (taktschritte) \
do { \
uint16_t a = taktschritte / 4; \
uint8_t b = taktschritte % 4; \
\
asm volatile( \
"0:" "\t" \
"sbiw %0, 1" "\n\t" \
"brne 0b" "\n\t" \
: "=w" (a) \
: "0" (a) \
); \
\
if (b > 0) NOP; \
if (b > 1) NOP; \
if (b > 2) NOP; \
} while(0)
Das erste ist asm ist gerade die Warteschleife _delay_loop_2 (uint16_t) aus <util/delay.h>
BTW: Anstatt rumzuwarten wäre für Ultraschall nicht besser ein Timer + PWM angebracht, falls frei?
Vielen Dank für Deine Hilfe.
Ich werde es noch in die edelay einbauen.
Btw: Grundsätzlich das Du recht mit dem Timer+PWM Methode, kein Thema, aber ich möchte ein 3-8 Port Multiplexer verwenden, sprich das man 7 Ultraschall sensoren ansprechen kann. Und da geht es halt nicht mit PWM.
Grüße und nochmal danke für Deine Hilfe.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.