Hallo, ich möchte einen möglichst exakten Zähler bauen, um mein Program exakt verzögern zu können. Dazu möchte ich Inline ASM in einem C Programm einsetzen, habe aber damit meine liebe Not. Einer Funktion wird ein "unsigned char length" übergeben. Dieser Wert gibt an, wie lange verzögert werden soll. Ich habe geschrieben: asm volatile ( " ld r2, 0" "\n\t" "start: add r2, 1" "\n\t" " cp r2, %e0" "\n\t" " brge start" : : "e" (length) : "r2" ); Zunächst soll in Register r2 eine Null geladen werden, die anschließend um eins inkrementiert wird. Anschließend soll dieser Wert mit den übergebenen Wert (length) verglichen werden und, wenn r2 kleiner als length ist, wieder nach oben gesprungen werden. So verzögere ich zwei Taktzyklen pro Durchlauf mit einem "Overhead" zu Beginn von einem Taktzyklus. Nur leider klappt das ganze nicht s, wie ich mir das vorstelle. AVRStudio sagt: Build started 28.9.2007 at 16:04:42 avr-gcc.exe -mmcu=atmega32 -Wall -gdwarf-2 -DF_CPU=8000000UL -Os -fsigned-char -MD -MP -MT sequence.o -MF dep/sequence.o.d -c ../sequence.c C:\DOKUME~1\User\LOKALE~1\Temp/ccGZhlMJ.s: Assembler messages: C:\DOKUME~1\User\LOKALE~1\Temp/ccGZhlMJ.s:693: Error: pointer register (X, Y or Z) required make: *** [prg.o] Error 1 Build succeeded with 0 Warnings... gcc plug-in: Error: Object file not found on expected location D:\Programmierung\Prg\default\Prg.elf Ich bin über Hinweise, wie ich meinen Fehler korrigieren kann oder meinen Zähler verbessern kann, dankbar :-) Gruß Kurt
@ Kurt (Gast) >ich möchte einen möglichst exakten Zähler bauen, um mein Program exakt >verzögern zu können. Dazu möchte ich Inline ASM in einem C Programm >einsetzen, habe aber damit meine liebe Not. Erfinde das Fahrrad nicht neu. Für kurze Verzögerungen gibt es _delay_us() bzw. _delay_ms(), die SIND ASM Makros und die SIND sehr genau. Längere genaue Verzögerungen macht man über einen Timer. >Ich bin über Hinweise, wie ich meinen Fehler korrigieren kann oder >meinen Zähler verbessern kann, dankbar :-) Zähler baut man mit Timern. MFG Falk
> _delay_us() bzw. _delay_ms() ...
Wobei das die `convenience functions' sind. _delay_loop_1() und
_delay_loop_2() sind die zugehörigen Basisfunktionen.
Exakt gesagt sind das übrigens keine Makros sondern inline-Funktionen.
Aber das hat rein technische Gründe.
Ich habe es mit _delay_us() versucht, habe schlechte Ergebnisse erhalten und bin dann in der AVR-Lib Doku auf folgendes gestoßen: "In order for these functions to work as intended, compiler optimizations must be enabled, and the delay time must be an expression that is a known constant at compile-time. If these requirements are not met, the resulting delay will be much longer (and basically unpredictable), and applications that otherwise do not use floating-point calculations will experience severe code bloat by the floating-point library routines linked into the application." Meine Vorgabe ist zur Compile-Zeitnicht konstant, daher funktioniert bei mir _delay_us() nicht. Also muss ich es selbst machen. Hat denn keine eine Idee, weshalb mein Inline ASM nicht funktioniert? Gruß und danke... Kurt
Kurt wrote: > ich möchte einen möglichst exakten Zähler bauen, um mein Program exakt > verzögern zu können. Was stört Dich daran, einen Timer zu benutzen ? Damit gehts auf den Zyklus genau, exakter gehts nicht. Peter
Kurt wrote: > Meine Vorgabe ist zur Compile-Zeitnicht konstant, daher funktioniert bei > mir _delay_us() nicht. Also muss ich es selbst machen. Nein, musst du nicht. Davon abgesehen, dass der Timer wohl wirklich die bessere Variante wäre, siehe: Beitrag "Re: Inline ASM: exakte Verzögerung" Wenn du's partout selbst schreiben willst, kannst du dir zumindest die dort referenzierten Funktionen als Vorlage nehmen. Diese Funktionen stehen übrigens mittlerweile in <avr/delay_basic.h>, nicht mehr in <avr/delay.h> (welches aber delay_basic.h mit einschließt). Der Grund ist einfach, dass <avr/delay.h> Warnungen produzieren soll, falls F_CPU nicht gesetzt ist oder ohne Optimierung compiliert wird, während diese Warnungen für die Funktionen in delay_basic.h nicht sinnvoll sind.
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.