Forum: Mikrocontroller und Digitale Elektronik Laufzeit einer Zählerschleife bestimmen


von Mikrofriendly R. (rennreh)


Lesenswert?

Guten Abend
Bei folgendem Codeschnipsel versuche ich mich bereits seit ein paar 
Stündchen, die Formel zur berechnung der Laufzeit zu bestimmen:
1
;                                     Zeile
2
warte:                          ;      1
3
warte_500ms:                       ;   2
4
  ldi counter0, CNT0  ; 1T             3
5
  ldi counter1, CNT1  ; 1T             4
6
  ldi counter2, CNT2  ; 1T             5
7
8
 cnt:                                  ;7
9
  dec counter0    ; 1T                  8
10
  brne cnt    ; 2T .. bei counter = 0 1T (einmal)       9
11
12
  ldi counter0, CNT0  ; 1T             11
13
  dec counter1    ; 1T                   12
14
  brne cnt    ; 2T .. bei counter = 0 1T (einmal)  13
15
16
  ldi counter1, CNT1  ; 1T                14
17
  dec counter2    ; 1T                     15
18
  brne cnt    ; 2T .. bei counter = 0 1T (einmal)    16  
19
ret        ; 3T                          17

Gut, zeile 2, 3, 4 und 16 brauchen zusammen 6 Takte und werden nur 
einmal durchlaufen.
Zeile 7 bis Zeile 9 benötigt, wenn Bedingung falsch ist immer 3 Takte. 
Mit berücksichtigung von der Schleife mit Anzahl CNT0 Durchläufen komme 
ich auf
c0 = 3*(CNT0-1)
DIe zweite schleife, gilt von Zeile 7 bis Zeile 13, sodass gilt:
c1 = (c0+4)*(CNT1-1)

Mit der dritten und letzten also Obersten Schleife, welche von zeile 7 
bis 16 werkelt kommt man auf:

Takte = (c1+4)*(cnt2-1)
mit einsetzen der zeitkonstenten:
Takte = ((3*(CNT0-1)+4)*(CNT1-1)+4)*(cnt2-1)

ich kann also durch probieren mit ganzahligen werten ein möglichst 
glattes Ergebnis für z.b. cnt2 erzielen um 500ms zu warten.

Ist die Ermittlung zur Laufzeit der Funktion so richtig wie ich es 
gemacht habe ?
Ich nutze den ATmega8 mit internen RC-Oszillator mit einem MHz; die 
interne Taktquelle ist nicht gerade die geneueste, lohnt es sich 
eigentlich so einen aufwand zu betreiben?
Und wie schnell schalten denn die Ausgänge ?

mfg

von :-) :-) :-) :-) (Gast)


Lesenswert?

Ein paar Stuendchen ? ... Der simulator laesst genau zaehlen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

:-) :-) :-) :-) wrote:
> Ein paar Stuendchen ? ... Der simulator laesst genau zaehlen.

Liefert aber keine Formel in Abhängigkeit der drei 8-Bit Werte CNTx, 
bzw. des 24-Bit Wertes, der sich daraus ergibt ;-)

von STK500-Besitzer (Gast)


Lesenswert?

>Ich nutze den ATmega8 mit internen RC-Oszillator mit einem MHz; die
>interne Taktquelle ist nicht gerade die geneueste, lohnt es sich
>eigentlich so einen aufwand zu betreiben?

Nein!

>Und wie schnell schalten denn die Ausgänge?

1 Takt.

Mach das mit einem Timer und gut ist's!

von Mikrofriendly R. (rennreh)


Lesenswert?

Das geht aber schnell bei euch :)

Ist dieser Zähler etwas besser, ich meine zählt er Hardwaremäßig oder 
ist der Atmel die gesamtezeit nur mit dieser funktion beschäftigt.
1
warte_500ms_b:
2
  push r24
3
  push r25
4
5
  clr r24
6
  clr r25
7
  
8
  ldi akku, 3
9
10
  cntb:
11
    sbiw r24, 1
12
  brne cntb
13
  dec akku
14
  brne cntb
15
16
  pop r25
17
  pop r24
18
ret

:-) :-) :-) :-) wrote:
> Ein paar Stuendchen ? ... Der simulator laesst genau zaehlen.

Nun also ich bin der Meinung man sollte einfach alles mal ausbrobiert 
haben. Der Simulator ist ja ne tolle Sache aber ich traue ihm nicht :)

Real auf dem oszi schaut alles etwas anders aus als es der simulator mir 
sagt :)

von Johann L. (gjlayde) Benutzerseite


Angehängte Dateien:

Lesenswert?

Falls man sich die Mühe doch machen will, weil zB kein Timer frei ist:

Was du willst ist wohl nicht, für den Codeschnippsel die Anzahl der 
Ticks zu berechnen, die er braucht, sondern umgekehrt: Du willst ne 
bestimmte Anzahl Ticks vertrödeln, und suchst Code der das tut.

Anbei ist ist ein Header für avr-gcc, der genau das macht: Beim Aufruf 
von exact_delay(1000) werden genau 1000 Ticks verbraten, beim Aufruf von 
exact_delay(1) genau einer, etc.

Das ganze ist eigentlich nur ein Assembler-Makro. Falls du in Assembler 
programmierst, kannst das direkt da keinkopieren...allerdings nur mit 
der Macht des GNU-Assemblers ;-)

In C sieht's so aus:
1
#include "exact-delay.h"
2
3
int main()
4
{
5
    exact_delay (1000);
6
    return 0;
7
}

Johann

von Johann L. (gjlayde) Benutzerseite


Angehängte Dateien:

Lesenswert?

...und für Assembler schält man einfach den ganzen C-Krempel ab: Der 
Aufruf ist dann zB
1
.include "exact-delay.inc"
2
.text
3
    _TICKS 1000, r24, r25

Johann

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

René K_punkt wrote:

> Ist dieser Zähler etwas besser, ich meine zählt er Hardwaremäßig oder
> ist der Atmel die gesamtezeit nur mit dieser funktion beschäftigt.

Er ist nicht etwas besser, er ist viel besser.

Er zählt parallel zu deinem Programm, bremst also nix aus. Er kann 
Interrupts auslösen in dem du zB eine Zählvariable erhöhen oder Flags 
setzen kannst.

Johann

von spess53 (Gast)


Lesenswert?

Hi

Im Web gibt es einen 'AVR Delay Loop Generator'. Gurgel hilft.

MfG Spess

von Mikrofriendly R. (rennreh)


Lesenswert?

Vielen Dank Johann und spess53 :)

Kann man diesen Hardwarezähler auch beliebig erweitern, z.b. wenn 16 bit 
(r24 und r25) nicht ausreichen ?
oder kann ich dies nur durch kaskadierung mit weiteren registern wie 
r26, r27 erreichen erreichen ?
was passiert wenn r24:r25 zählt und zeitgleich r26,r27 mit zählen durch 
sbiw r26,1 beginnt ?

ich meine ist nur ein zähler als hardware im atmel implementiert ?
und dieser zähler hat auch "nur" 16 bit ?

mfg

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

spess53 wrote:

> Im Web gibt es einen 'AVR Delay Loop Generator'. Gurgel hilft.

hmmm... wozu kompliziert, wenn's auch einfach geht?

Der Assembler kann doch alles, was man braucht.

So muss man sich weder irgendeine Executable aufm Rechner installieren 
noch ständig Code hin- und her zu kopieren und immer wieder Werte 
eintippsen.

Größen wie F_CPU etc. lässt man vom Präprozessor verdauen, und der kann 
auch meckern wenn Werte nicht passen oder ne Schleife aufgrund ner 
Division, die nicht genau aufgeht, ungenau wird -- wenn man sowas haben 
will.

Wer braucht dafür nen extra Loop Generator??? Am besten noch in Excel...

Johann

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

René K_punkt wrote:

> ich meine ist nur ein zähler als hardware im atmel implementiert ?
> und dieser zähler hat auch "nur" 16 bit ?

Alle Zähler, die hier vorgestellt wurden, sind rein in Software und 
realisieren eine Verzögerung über Rungammeln in einer Warteschleife.

Hardware-Zähler operieren auf eigenen Spezial-Registern (SFRs), über die 
sie auch konfiguriert werden. Sie haben mit den normalen µC-Registern 
wie R25 nix zu tun.

Schnapp dir am besten mal ein AVR-Handbuch oder wag einen Blick ins 
Tutorial, um ne Vorstellung zu bekommen, was ein Hardware-Zähler 
überhaupt ist.

Johann

von Spess53 (Gast)


Lesenswert?

Hi

>ich meine ist nur ein zähler als hardware im atmel implementiert ?
>und dieser zähler hat auch "nur" 16 bit

Die Ausstattung mit Timern hängt vom kongreten AVR ab. Ausserdem kann 
man einen Timer auch für verschiedene Funktionen benutzen. Z.B. du 
konfigurierst einen Timer so, das er alle 10ms einen Interrupt auslöst. 
In der Interruptroutine zählst du eine 'Speichestelle' herunter. Wenn du 
die z.B. am Anfang mit 100 lädst ist beim Stand 0, 1s vergangen. Das 
kann man dann auswerten. Wenn du in dem Interrupt 2 'Speicherzellen' 
zählst, kannst du mit einem Timer auch zwei verschiedene Zeiten 
erzeugen.

MfG Spess

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
Noch kein Account? Hier anmelden.