Hallo! Hab folgende C-Funktion geschrieben mit eingebettetem Assembler-Code, welche nichts weiter machen soll als einen gewissen Delay. ...void delay05(void) ...{ ... asm volatile ... ( ... // ============================= ... // delay loop generator ... // 8333333 cycles: ... // ----------------------------- ... // delaying 8333325 cycles: 297 " ldi R17, #37h" "\n\t" 298 "WGLOOP0: ldi R18, #D6h" "\n\t" 299 "WGLOOP1: ldi R19, #EBh" "\n\t" ... "WGLOOP2: dec R19" "\n\t" ... " brne WGLOOP2" "\n\t" ... " dec R18" "\n\t" ... " brne WGLOOP1" "\n\t" ... " dec R17" "\n\t" ... " brne WGLOOP0" "\n\t" ... // ----------------------------- ... // delaying 6 cycles: 306 " ldi R17, #02h" "\n\t" ... "WGLOOP3: dec R17" "\n\t" ... " brne WGLOOP3" "\n\t" ... // ----------------------------- ... // delaying 2 cycles: ... " nop" "\n\t" ... " nop" "\n\t" ... // ============================= ... : ... : ... ); ...} Ich bekomme jedoch folgende Fehler vom Compiler: C:\TEMP\ccXbaaaa.s: Assembler messages: C:\TEMP\ccXbaaaa.s:297: Error: Bad expression C:\TEMP\ccXbaaaa.s:297: Error: garbage at end of line C:\TEMP\ccXbaaaa.s:298: Error: Bad expression C:\TEMP\ccXbaaaa.s:298: Error: garbage at end of line C:\TEMP\ccXbaaaa.s:299: Error: Bad expression C:\TEMP\ccXbaaaa.s:299: Error: garbage at end of line C:\TEMP\ccXbaaaa.s:306: Error: Bad expression C:\TEMP\ccXbaaaa.s:306: Error: garbage at end of line die Zeilen hab ich mit Zahlen markiert! Was ist daran falsch und wie muss es richtig heißen?
supi funzt! #D6h hatte ich genommen weil ich das von der Asm-Programmierung mit dem 80C517 kannte. Urpsürnglich stand aber &D6 dort, aus dem AVRDelayLoop-Generator, dort hatte ich aber auch einen Fehler ;)
Ob das so gut geht wenn man einfach in einem eingebetteten Assemblercode ein paar Register überklatscht ohne den Compiler zu informieren? Auch wenn es sich um eine eigenständige Funktion handelt hätte ich hierbei trotzdem schwerste Bedenken. Das muss ja nicht notwendigerweise bedeuten, dass der Compiler alle seine Register leerräumt. Aber er wird es ja merken, wenn auf einmal seltsame Effekte auftreten. Gruss, Peter
Hast du nen besseren Vorschlag was man machen könnte? Ich hatte zuerst auch folgenden Code: void delay05(void) { int i; for(i=0; i < 833; i++) { asm volatile("nop"::); } } Macht genau das selbe, nur das Problem ist nur das ich nicht weiß wieviel Zyklen die For-Schleife pro Durchgang beansprucht und bei meinem Programm muss ich relativ genau sein.
> Hast du nen besseren Vorschlag was man machen könnte? Ich benutze den angehängten Code dafür. Ist zwar etwas umfangreicher (51 Bytes), dafür aber auch genau und sauber/sicher. > ich nicht weiß wieviel Zyklen die For-Schleife pro Durchgang beansprucht und bei meinem Programm muss ich relativ genau sein. Ich habe den Code mittels AVR-Studio ausgemessen. Schmittchen.
genau. das mit dem ausmessen hab ich auch immer so gemacht. das klappt recht gut, und dann haste nicht diese assembler krücke.
Das mit dem eingebetteten Assembler ist ja an sich ok, man sollte nur die Clobber-Liste ausfüllen, damit der Compiler weiss, welche Register man für seinen eigenen Code in Beschlag nimmt. Hier hat sich nämlich ein netter Kollege mal die Mühe gemacht, einen Code-Generator (Assembler) für Warteschleifen zu programmieren, der einem für jede gewünschte Verzögerung den exakten Code ausgibt. Den so erzeugten Assembler-Code kann man z.B. gut in C einbetten. Wenn man einmal die zusätzliche Zeit für den Funktionsaufruf in C ermittelt hat, kann man sich fortan Verzögerungsroutinen auf den Taktzyklus genau programmieren ohne das Timing mit dem AVR-Studio jedesmal zurechtfutscheln zu müssen. Nur mal so als Tip. Gruss, Peter
hmmm.. die frage ist: dauert der funktionsaufruf nicht länger für ne warteschleife, die 3 regs benutzt, als eine, die 2 benutzt? der compiler muss doch vorher dann die regs sichern und zurückholen... oder ist die clobber liste global?
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.