mikrocontroller.net

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


Autor: Mikrofriendly Rene (rennreh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend
Bei folgendem Codeschnipsel versuche ich mich bereits seit ein paar 
Stündchen, die Formel zur berechnung der Laufzeit zu bestimmen:
;                                     Zeile
warte:                          ;      1
warte_500ms:                       ;   2
  ldi counter0, CNT0  ; 1T             3
  ldi counter1, CNT1  ; 1T             4
  ldi counter2, CNT2  ; 1T             5

 cnt:                                  ;7
  dec counter0    ; 1T                  8
  brne cnt    ; 2T .. bei counter = 0 1T (einmal)       9

  ldi counter0, CNT0  ; 1T             11
  dec counter1    ; 1T                   12
  brne cnt    ; 2T .. bei counter = 0 1T (einmal)  13

  ldi counter1, CNT1  ; 1T                14
  dec counter2    ; 1T                     15
  brne cnt    ; 2T .. bei counter = 0 1T (einmal)    16  
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

Autor: :-) :-) :-) :-) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein paar Stuendchen ? ... Der simulator laesst genau zaehlen.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 ;-)

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Mikrofriendly Rene (rennreh)
Datum:

Bewertung
0 lesenswert
nicht 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.
warte_500ms_b:
  push r24
  push r25

  clr r24
  clr r25
  
  ldi akku, 3

  cntb:
    sbiw r24, 1
  brne cntb
  dec akku
  brne cntb

  pop r25
  pop r24
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 :)

Autor: Johann L. (gjlayde) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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:
#include "exact-delay.h"

int main()
{
    exact_delay (1000);
    return 0;
}

Johann

Autor: Johann L. (gjlayde) Benutzerseite
Datum:
Angehängte Dateien:

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

Johann

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

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

MfG Spess

Autor: Mikrofriendly Rene (rennreh)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.