Forum: Compiler & IDEs Warteschleife in Assembler


von Lars (Gast)


Lesenswert?

Hallo,
Ich bin noch ungeübt mit Assembler und habe eine Frage, wie kann ich
das Programm dazu bringen eine halbe Sekunde zu warten?


.NOLIST
.INCLUDE "8535def.inc"
.LIST

.DEF temp = R16

  RJMP anfang

anfang:
  LDI temp, 0xFF
  OUT DDRA, temp
  OUT DDRB, temp
  OUT DDRC, temp
  LDI temp, 0x00
  OUT DDRD, temp
  LDI temp, 0x0F
  OUT PORTB, temp
  LDI temp, 0xF8
  OUT PORTC, temp
  NOP
  NOP
  RCALL warten
  RCALL warten
  LDI temp, 0x00
  OUT PORTB, temp
  NOP
  NOP
  RCALL warten
  LDI temp, 0x10
  OUT PORTB, temp
  NOP
  NOP
  RCALL warten
  LDI temp, 0x00
  OUT PORTB, temp
  NOP
  NOP
  RCALL warten
  LDI temp, 0x10
  OUT PORTB, temp
  NOP
  NOP
  RCALL warten

warten:
  RET

Ich weiß nicht wie ich es anstellen soll, wer kann mir das Codestück
für die warten Funktion schreiben?
Ich danke jetzt schon.
Gruß, Lars

von Marcel Meyer (Gast)


Lesenswert?


von chrissy (Gast)


Lesenswert?

Also entweder, wie gesagt, per Timer. d.h. Vorteiler und Zählschritte
mit der Taktfrequenz so hintüddeln, daß er die Gewünschte Zeit läuft.

Oder mit einrr verschachtelten Schleife. Das erfordert bißchen Rechnen,
denn du musst dir überlegen, wie viele Takte die Schleifen jeweils
brauchen incl. Zählstand verändern, vergleichen und springen.

Habe auch mal für dich gegoogelt und einige Anfänger-Hilfen
rausgesucht. Irgendwie sieht der zweite Link aber komisch aus....

http://www.avr-asm-tutorial.net/avr_de/
http://www.elektronik-projekt.de/include.php?path=content/articles.php&contentid=75&PHPKITSID=ae47b49717e954b4c35feeb077787095

von Jürgen Schuhmacher (Gast)


Lesenswert?

Falls Du tatsächlich noch nicht so firm bist, ein kleiner Einwand von
mir:

"... mit einrr verschachtelten Schleife. Das erfordert bißchen
Rechnen, denn du musst dir überlegen, wie viele Takte die Schleifen
jeweils brauchen incl. Zählstand verändern, vergleichen und
springen."

DIES KLAPPT ALLES NUR BEI LINEAREN PRGRAMMEN! - also ohne multi
threadinung und speziell das ausloten des Zählers haut nur hin, wenn Du
die Interrupte überwachst und mitzählst (oder keine hast!!).

Korrekt läuft sowas immer über einen Hardwarezähler (oder ein in Form
eines zuverlässigen Interrupts als solcher agierender Softwarezähler),
der am Ende einer Bedarfsroutine auf einen defnierten Stand gebracht
wird, der exakt der gwünschten Wartezeit abzüglich der aktuell
benötigten Durchlaufzeit der zurückgelegten Routine entspricht.
Letztere ist nämlich empirisch messbar und im Falle einer eindeutigen
Interrupthierachie auch deterministisch festlegbar (also rechenbar).
Der Timer hat dann also immer einen idealen Wert, den er runter zählt.
Nun muss nur auf Null geprüft werden oder noch besser, der Timer löst
einen Interrupt aus. Der Trick dabei ist der, daß diese Vorkompensation
jegliche Laufzeit des Programmes eliminiert.

Ideal ist natürlich ein programmierbarer Interrupt: Man sollte immer
zusehen, daß man soetwas wenigstens einmal im Prozzi hat, und vor doert
aus sich eine Systemzeit ableitet. Alle anderen Funktionen können dann
in Software realisiert werden, also z.B. die aktuelle Systemzeit
merken, die Zeitdauer dazuaddieren, in einer Endvariablen speichern und
in der gewünschten Zielroutine einfach diese Endvariable auf Erreichen
des Timerwertes prüfen.

Ich habe mal vor Jahren ein komplettes Echtzeitsystem auf die Art
geschrieben: Alles reines Software, es gab nur einen externen Timer.

von egal (Gast)


Lesenswert?

ist: gcc-Forum (hier)
besser: µC/Elektronik-Forum (nicht hier)

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.