Forum: Mikrocontroller und Digitale Elektronik Verzögerung mit Assembler


von Christian R. (Gast)


Lesenswert?

Hallo,

ich möchte mittels Assembler eine Verzögerung einbauen. Habe aus dem LCD 
Beispiel aus dem Tutorial schonmal folgendes gefunden:

.ifndef XTAL
.equ XTAL = 4000000
.endif

delay50us:                              ; 50us Pause
           ldi  temp1, ( XTAL * 50 / 3 ) / 1000000
delay50us_:
           dec  temp1
           brne delay50us_
           ret

Wofür sind die drei ersten Zeilen eigentlich gut ?? In XTAL steht 
anscheind schonmal die Frequenz von 4Mhz drin, später wird dann etwas in 
temp1 geladen, aber woraus setzt sich das genau zusammen, bzw. was muss 
ich für die 50us rechnen ??

Also bei 4Mhz dauert ein Taktzyklus ja 250ns, dh. ich muss bei einer 
Verzögerung von 50us 200 Taktzyklen abarbeiten !?

Ich hoffe einer kann mir das jetzt noch eindeutig erklären,

Danke,
Christian R.

von Hannes L. (hannes)


Lesenswert?

Also bei aller Freundschaft, das hat Karl heinz im Tutorial sehr genau 
und verständlich beschrieben. Lies einfach mal den Artikel zu Ende oder 
nochmal, falls Du die Erklärung übersehen hast.

...

von Christian R. (Gast)


Lesenswert?

Sorry, hatte da wirklich zu schnell gescrollt und den Teil überlesen

Danke,
Christian R

von Michael U. (Gast)


Lesenswert?

Hallo,

naja, warum selber rechnen, wenn es der Präprozessor des Assembler auch 
kann. ;)

XTAL ist 4 000 000 Hz, also 4 000 000 Schwingungen (damit auch Takte des 
AVR) pro Sekunde.
Das * 50 sind 200 000 000 Takte pro 50 Sekunden.
3 ist die Anzahl Taktzyklen für dec (1) und brne (2).
Also sind 200 000 000 / 3 =  66 666 666 Takte für 50 s mötig-
Die nun noch durch 1 000 000 geteilt macht 66 Schleifendurchläufe für 
50µs

Der Takt des ldi vor der Schleife wird am Schluß vom brne kompensiert, 
der braucht nur 1 Takt, wenn die Bedingung nicht erfüllt ist.

Für "normale" Genauigkeiten machen sich solche Rechnereien immer gut, 
weil man bei Änderung des Taktes nur eine Zuweisung anpassen muß.

Bei mir sieht das meist so aus:
.equ    F_CPU           = 8000000
.equ    CYCLES_PER_US   = (F_CPU/1000000)

.equ  IRQ_TIME  = 10  ; IRQ-Zeit in ms

.equ  VORTEILER    = 64
.equ  COUNT_IN    = F_CPU/VORTEILER  ; Vorteiler 64 - 125000Hz

.equ    TCONST_TIME     = COUNT_IN/(1000/IRQ_TIME)
.equ  COUNT_SEK    = 1000/IRQ_TIME  ; Wert für IRQ-Zähler

.equ  REPEAT_WAIT    = 1000/IRQ_TIME  ;1000ms
.equ  REPEAT_LOOP    =  100/IRQ_TIME  ;Wiederholzeit

.equ  I2C_FREQUENZ  = 100000
.equ  I2C_CLOCK    = ((F_CPU/I2C_FREQUENZ)-16)/2

Gruß aus Berlin
Michael

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.