PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : flexible Wait-Routine in Assembler



skyrider
19.05.2005, 16:33
Hi @all

da ich mit verschiedenen AVR und unterschiedlichen Taktfrequenzen arbeite, habe ich eine kleine Routine geschrieben die unabhängig von Prozessortakt (1-20 MHz) arbeitet. Sie arbeitet nicht 100% us genau, aber im Bereich 1-255 ms zuverlässig und sollte für die meisten Anwendungen ausreichend sein.

Für Anregungen und Verbesserungsvorschläge wäre ich dankbar

VG
Skyrider




.def temp = r16


.equ cputakt = 8000000 ;arbeitet im Bereich von (1 - 20 MHz)
.set count_ms = cputakt / 4000 - 1
;ergibt in wait_ms ca.1ms vom Aufruf aus

.include "tiny2313.inc" ;Startroutine für den Tiny2313



.MACRO wait_ms

ldi temp, @0 ;Lade temp mit Zähler (in ms)
rcall delay_ms ;Aufruf Verzögerungschleife

.ENDMACRO



start:

wait_ms(5) ;Verzögerung um 5ms
wait_ms(20) ;nochmal 20ms


loop:
rjmp loop ;tu nix Schleife

; ************************************************** ******************
; delay_ms verzögert um x ms
; Parameter : Zeit in ms (1-255) in temp, in Z-Register keine Änderung
; Rückgabe : keine
; ************************************************** ******************

delay_ms:
push ZL ;Z auf den Stack retten
push ZH
delay_ms_1:
ldi ZH, HIGH(count_ms) ;Lade höherwertiges Byte nach Z
ldi ZL, LOW(count_ms) ;Lade niederwertiges Byte nach Z
delay_ms_2:
sbiw ZL,1 ;subtrahiere 1 von Z
brne delay_ms_2 ;solange bis Z = 0
dec temp ;temp um 1 herunterzählen
brne delay_ms_1 ;solange bis temp = 0
pop ZH ;Z vom Stack zurückholen
pop ZL
ret

OVF1_event:
reti

Florian
19.05.2005, 16:37
Hi skyrider!
Das ist auch mal eine pfiffige Idee! ;o)
Finde ich lustig!

skyrider
19.05.2005, 16:48
Hi Florian,

was meinst du den mit Lustig ???
Ich fand es immer nervig, die Delay Zeiten anzupassen.
Hast du noch eine andere Lösung ? vieleicht auch für den us Bereich ?

VG
Skyrider

pebisoft
19.05.2005, 16:54
hallo, finde ich ganz toll. gibt es auch eine für us.
ich habe festgestellt, das die _delay.... von winavr nicht so funktionieren.
warum habe ich noch nicht rausgefunden.
mfg pebisoft

Florian
19.05.2005, 16:58
Hi Skyrider!
Das "lustig" war nicht abwertend gemeint, ich wär nur irgendwie nie auf die Idee gekommen, deswegen finde ich die Lösung gut!
Allerdings ist natürlich der Delay-Loop-Generator (Suchfunktion hier im Forum benutzen *g*) für ganz Rechenfaule bzw. Anfänger noch praktischer.
Aber so spontan fällt mir auch keine Verbesserung zu Deiner Lösung ein! ;o)
Für Anwendungen, die nicht allzu zeitkritisch sind, finde ich sehr praktisch!
Ich lasse mir das ganze nochmal durch den Kopf gehen, aber im Grunde genommen finde ich die Lösung nicht schlecht!

lekro
19.05.2005, 17:37
warum habe ich noch nicht rausgefunden. Lies die Doku. Die delay-Funktionen von WinAVR haben eine Begrenzung der Wartezeit. Für längere Wartezeiten als ein paar ms sollte man evtl. selbst eine Wartefunktion schreiben oder Timer verwenden.

pebisoft
19.05.2005, 18:00
da nützt kein lesen der doku. beim srf04 brauche ich 10us und 200us wartezeit. schafft die routine _delay... nicht. der srf04 spricht nicht an.
eine selbst erstellte eingebundene routine in asm die es ganz genau einhält bringt es.
mfg pebisoft

skyrider
19.05.2005, 19:33
@pebisoft

freut mich das die Routine dir gefällt und du Sie in WinAVR einbinden kannst (Vielleicht kannst du das Ergebnis dann mal posten, ist bestimmt für einige Interessant).
Die Routine ist leider nicht so genau in den Grenzbereichen, aber für einfache Aufgaben sollte es reichen.
Für den us Bereich habe ich mir auch schon den Kopf zerbrochen.
Ist mir aber bis jetzt durch die benötigten Zyklen für RCALL .. RET nur für 4 - 16 MHz mit einer Abweichung von +-12% gelungen.
Würde mich mal interessieren mit welcher Formel die das mit BASCOM und WINAVR machen.
Vielleicht hat ja jemand einen Tip (Habe auf der Homepage bei einen der "Gurus" einmal eine Routine gesehen die ab 2 us arbeitet). Weiss leider nicht mehr wo und ob das von der Frequenz abhängig war.


@Florian

hab ich auch nicht als "abwertend" aufgefasst und sollte auch nicht so klingen O:)
Hätte ja sein können, dass du eine andere Routine "im Keller" liegen hast.
Den Generator habe ich auch im Einsatz (ist echt Klasse!), da ich aber mit 3 verschiedenen AVR-Typen (4,8,16 MHz) zum testen arbeite, die alle auf gemeinsame Include-Dateien zugreifen muss ich jedesmal die Werte anpassen oder die Dateien kopieren. Dies ist für die Entwicklung recht mühsam und fehlerträchtig.
Auch ist es nicht effizient z.B 3x eine identische Schleife mit unterschiedlichen Werten ins Flash zu brennen, wenn es doch einfacher geht O:)

Viele Grüße
Skyrider

Florian
19.05.2005, 19:40
hab ich auch nicht als "abwertend" aufgefasst und soltte auch nicht so klingenNa dann ist ja gut! ;o)

Den Generator habe ich auch im Einsatz (ist echt Klasse!)Ja, wobei ich ihn mitlerweile kaum noch verwende, keine Ahnung warum! *g*
Ich arbeite meistens mit einem mit 16MHz betriebenen AVR, da ich einige Zeitkritische Funktionen brauche, aber auch, weil ich mir diese Mühe ersparen will! ;o)