Immer wieder kommen Zeitschleifen folgender Form vor :
ldi Timer1, XXX
TimeLoop1: ldi Timer2, YYY
TimeLoop2: dec Timer2
brne TimeLoop2
dec Timer1
brne TimeLoop1
Kann da nicht mal einer ein Java Schnipsel schreiben, in das man nur
den uC Type und die Anzahl der zu verbratenden Tackte eingibt und das
dann die optimalen Teiler ausspuckt ?
Oder gibt es so etwas ? Wenn ja, dann wo ?
gruß Ede
Ede wrote:
> Kann da nicht mal einer ein Java Schnipsel schreiben, in das man nur> den uC Type und die Anzahl der zu verbratenden Tackte eingibt und das> dann die optimalen Teiler ausspuckt ?
Warum denn kompliziert, wenns auch einfach geht?
Das geht direkt im Assembler ohne riesen Umwege über Java:
http://www.mikrocontroller.net/attachment/416/Mdelay.asm
Und wenns nicht auf den Zyklus genau sein muß, einfach die letzten 5
Instruktionen weglassen.
Peter
Merk dir schon mal KAVRCalc für die Zeit, wenn du die
Software-Warteschleifen satt bist und du mit richtigen Timern arbeiten
willst:
http://b9.com/elect/avr/kavrcalc/index.html
Hallo,
eigentlich kommen sie (bei mir?) eher selten vor, BusyLoops halten den
Laden nur unnötig an, längere Pausen erledigt ein Timerinterrupt
nebenbei.
Ansonsten: laß doch den Assembler rechnen...
1
.equ F_CPU = 16000000
2
.equ CYCLES_PER_US = ((F_CPU+500000)/1000000)
3
4
.macro load_p ; lädt 16Bit @1 nach @0 High und @0 Low
5
ldi @0H,HIGH(@1)
6
ldi @0L,LOW(@1)
7
.endmacro
8
9
wait_10ms:
10
push ZL
11
push ZH
12
13
load_p Z,10000*(CYCLES_PER_US/4)
14
; 10 mS warten, 4 = Anzahl Befehls-Zyclen vom sbiw + brne
15
16
d_loop:
17
sbiw Z,1
18
brne d_loop
19
20
pop ZH
21
pop ZL
22
23
ret
Ist jetzt nur schnell rauskopiert, passt nicht unbedingt zusammen, die
Absicht sollte aber erkennbar sein.
Gruß aus Berlin
Michael
Ich benutze einfach immer den Simulator - Einmal "run to cursor" und
dann weiß ich, wie viel der braucht.
Ich habe für meine Bedürfnisse Makros geschrieben, die anhand der
geforderten Taktzahl das jeweils günstigste Verfahren wählen:
- einzelne NOPs
- inline-Zählschleife
- Subroutine mit Zählschleife
Da steht dann nur
delay 1234
Dynamische Laufzeiten kann man ja nachrüsten.
Für gehobene Ansprüche natürlich den Timer bemühen - blockiert dann
nicht gleich den ganzen µC.
Danke für die beiden Code Schnipsel aber beide gehen z.B. im Tiny12
nicht!
(kein Ram bzw sbwi)
deswegen auch die uC Auswahl
danke auch für den Link zu dem Delay Rechner´,
der geht wiederum nur für AVR
Gruß Ede
Warum schreibst du dir nicht einfach mehrere Zeitschleifen für
verschiedene Controller nach dem Muster von Peter Dannegger, entweder
als Makro oder als Unterprogramm? Diese lassen sich direkt aufrufen,
und wenn du den Delay einen Zyklus länger oder kürzer haben möchtest,
änderst du einfach das Argument. Das ist doch viel angenehmer als
jedesmal ein Java-Programm zu starten und die berechneten Ergebnisse
in deinen Programmcode einzutragen.
Diese Zeitschleifen für zwei verschiedene AVRs, zwei PICs und
vielleicht noch den 8051 zu schreiben dürfte schneller gehen als im
Netz einer Universallösung zu finden.
Zudem kannst du die Zeitschleifen für jeden Controller so optimieren,
dass du die jeweils bestmögliche Zeitauflösung bekommst. Peters
Vorschlag bspw. liefert zyklengenaue Delays, während dein obiges
Muster auf AVRs eine Zeitauflösung von 3 Zyklen hat und damit nicht
sehr gut für diesen Controllertyp geeignet ist.
Sehr einfache Delay Routine
Die Register r16 (temp) und r17 (temp1) sind destruktiv
In r30:r31 (zl:zh) hinterlegst du die Zeit der Warteschleife in ms
z.B. 2 Sekunden Delay
ldi zh,0x07 ;0x07d0=2000
ldi zl,0xd0
rcall simple_wait
Funktioniert mit ALLEN AVR's (auch Tiny12)
Die Verzögerung ist auf 1MHz XTal abgeglichen (ms genau)
Bei Delays <65sec mußt du halt Z erweitern.
/*
very simle delay routine
uses
-no interrupts
-r16
-r17
-z for input (r30:r31)
-labels temp and temp1
1ms delay @ 1 MHz
*/
simple_wait:
wait5:
.def temp=r16
.def temp1=r17
ldi temp,0xf7 ;do not edit!!!!
ldi temp1,0x01
wait_endtime10:
dec temp
tst temp
brne wait_endtime10
dec temp1
tst temp1
brne wait_endtime10
ldi temp,0xf7
nop
nop
ldi temp1,0x01
sbiw zl:zh,1
tst zl
breq wait_endtime20
rjmp wait_endtime10
wait_endtime20:
tst zh
brne wait_endtime10
ret
> Danke für die beiden Code Schnipsel aber beide gehen z.B. im Tiny12> nicht!> (kein Ram bzw sbwi)>> deswegen auch die uC Auswahl
Warum nimmst du eigentlich keinen Tiny13, der genausoviel kostet, wie
ein Tiny12, aber RAM hat? Der Tiny12 ist immerhin der einzige AVR, der
kein RAM hat (neben dem Tiny11, der aber glaube ich abgekündigt ist).
> eigentlich kommen sie (bei mir?) eher selten vor, BusyLoops halten den> Laden nur unnötig an, längere Pausen erledigt ein Timerinterrupt> nebenbei.
Vor allem: Wenn auch noch andere Interrupts kommen, wird das Timing der
Delay-Loop verhunzt, es sei denn, man sperrt während des Delay alle
Interrupts.
> Der Tiny12 ist immerhin der einzige AVR, der kein RAM hat (neben dem> Tiny11, der aber glaube ich abgekündigt ist).
Der Tiny12 ist "Not recommended for new designs" und wird wohl über
kurz oder lang ebenfalls rausfliegen. Unverständlicherweise scheint er
sich aber bei den Forenteilnehmern seit Anfang dieses Jahres
wachsender Beliebtheit zu erfreuen. Gab's den vielleicht bei Pollin zu
Weihnachten in der 100er-Tüte für 3,95 Euro?
Hallo,
@ Gast 18.03.2008 22:31:
da ich das jetzt zum 2. Mal so sehe:
dec temp
tst temp <----
gibt es einen AVR, der bei dec das Zero-Flag nicht beeinflußt?
brne wait_endtime10
Gruß aus Berlin
Michael