Forum: Mikrocontroller und Digitale Elektronik Assemblercode Wartezeitberechnung


von Felix S. (fest)


Lesenswert?

Es geht um den Befehl

>Zeit = Zahl zwischen 260 und 10.000
>Ausgleich = 260
>Pauseus Zeit - Ausgleich

Dieser bedeutet:

Warte Zeit minus Ausgleich in Mikrosekunden, tue nichts in der Zeit

Wie sieht ein Assemblercode für den PIC 16F628A aus, der genau diese 
Operation ausführt?

Quartz ist 20Mhz.

Grüße

von Peter D. (peda)


Lesenswert?

Ich kann nur AVR Assembler:

Beitrag "Re: 24h Schalter mit Attiny 12"

Vom Prinzip her, sollte das aber auch auf den PIC umzusetzen sein:
Man nehme die nötige Zahl an Bytes, lade sie entsprechend vor und zähle 
solange runter, bis alle 0 sind.

Wenn ich mich recht erinnere, können einige PICs keinen Übertrag und 
auch das auf 0 Testen ist komplizierter.


Peter

von holger (Gast)


Lesenswert?

>Wenn ich mich recht erinnere, können einige PICs keinen Übertrag und
>auch das auf 0 Testen ist komplizierter.

Sonst gehts noch oder was?

von Reiner O. (elux)


Lesenswert?

Für ganz besonders Faule (also auch mich!) gibt es im Netz den "AVR 
Delay Loop Generator", der gleich Assembler-Code ausspuckt. Sollte auf 
dem PIC eigentlich prinzipiell auch verwendbar sein -> mit ein bißchen 
umbauen...


Gruß aus Berlin

Elux

von Lehrmann M. (ubimbo)


Lesenswert?

Peter Dannegger schrieb:
> Wenn ich mich recht erinnere, können einige PICs keinen Übertrag und
> auch das auf 0 Testen ist komplizierter.

Die AVR ler werdens nie einsehen ... Warum kann man nicht einfach 
objektiv sein und sich das eingestehen, dass die Microncontroller in 
dieser Hinsicht gleichwertig sind. Sowas von verbohrt ...



Zur den Warteschleifen:

http://www.sprut.de/electronic/pic/programm/lauflicht/lauflich.htm

Hier ist's ein bisschen beschrieben (Tabelle mit Takten, etc.).

Ansonsten bei Google "pic delay loop" suchen - dann kommt das:
http://www.google.de/search?q=pic+delay+loop&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:de:official&client=firefox-a

Erster Eintrag ist schon ein Onlinerechner - die anderen Ergebnisse sind 
gleichwertig.

von MaWin (Gast)


Lesenswert?

> Wie sieht ein Assemblercode für den PIC 16F628A aus,
> der genau diese Operation ausführt?

Timer auf irgendeine Zählweise initialisieren, eventuell schon am Anfang 
des Programms.

Erwarteten Endwert berechnen.

Wiederholt den Timer abfragen, bis der nötige Wert erreicht ist.


Denn alle anderen Methoden kommen nicht damit klar, wenn in deine 
Warteschleife ein Interrupt reinhaut.

Du weisst noch nicht, was Interrupts sind ?

Macht nichts, du freust dich, wenn deine Routine auch dann richtig 
wartet, wenn du Interrupts mal benutzt.

von Felix S. (fest)


Lesenswert?

Zeit = Zahl zwischen 260 und 10.000 => Sie ändert sich => Die Zeit muß 
live berechnet werden. Da hilft kein Onlinerechner.

von Peter D. (peda)


Lesenswert?

Lehrmann Michael schrieb:
> Peter Dannegger schrieb:
>> Wenn ich mich recht erinnere, können einige PICs keinen Übertrag und
>> auch das auf 0 Testen ist komplizierter.
>
> Die AVR ler werdens nie einsehen ... Warum kann man nicht einfach
> objektiv sein und sich das eingestehen, dass die Microncontroller in
> dieser Hinsicht gleichwertig sind. Sowas von verbohrt ...


Ich hab extra nochmal nachgesehen, z.B. der PIC12F629 kann keinen 
Übertrag abziehen. Steht so jedenfalls in der Beschreibung des 
SUBWF-Befehls.

Und einen 0-Test über mehrere Bytes Subtraktion kennt der PIC auch 
nicht.

Ich hätte eigentlich gedacht, ein PIC-er sollte seine PICs besser kennen 
als ein AVR-er.

Du kannst mir aber gerne eine Zählschleife bis 0 über 5 Bytes mit dem 
PIC zeigen, die nur 6 Befehle lang ist.


Peter

von (prx) A. K. (prx)


Lesenswert?

Solange das Timing der einzelnen Befehle leicht reproduzierbar ist, ist 
es für programmierte Zeitschleifen schnurz ob AVR oder PIC oder ein 
anderer dieser einfacher 8-Bitter. Man schaut im Manual nach was der 
einzelne Befehl an Zeit benötigt, damit hat es sich.

Carry und Overflow-Flags (letzteres braucht man sowieso nur mit 
Vorzeichen, also hier nicht) sind überflüssig, ein 0-Test reicht auch 
bei Zählern über 8 Bits aus. Sowas wie 
countLo/condbranch/countHi/condbranch vorwärts oder rückwärts geht in 
allerlei Varianten und Schreibweisen immer, die geringe Abweichung alle 
256 Schritte dürfte kaum je eine Rolle spielen und falls doch kann man 
sie passend einrechnen.

Ja, manche Prozessoren können manche Dinge besser als andere, so haben 
AVRs das kumilierende Z-Flag bei Subtraktionen, was manches vereinfacht, 
dafür verbraten PICs für sowas keine Register und haben meist mehr 
Programmspeicher bei vergleichbaren Modellen (nicht ganz ohne Grund ;-). 
Kein Grund für einen Krieg, bei Zeitschleifen führt man kein Wettrennen 
durch und solange der Code ins ROM passt...

Haarig wird es erst, wenn die Laufzeit eines Befehls nicht mehr einfach 
aus dem Manual hervorgeht. Beispielsweise wenn bei 32-Bittern von 
Taktfrequenz und Code-Alignment abhängige Wartezyklen des 
Programmspeichers und irgendwelche Pufferspeicher darin eingehen. Dann 
ist es klüger, die Laufzeit der Schleife beim Start des Programms einmal 
zu kalibrieren (z.B. über Timer messen wie lang für N=1000, ergibt 
ns/iteration). Sowas funktioniert dann auch in C, unabhängig vom Grad 
der Optimierung des Compilers.

von (prx) A. K. (prx)


Lesenswert?

Felix Sturm schrieb:

> Zeit = Zahl zwischen 260 und 10.000 => Sie ändert sich => Die Zeit muß
> live berechnet werden.

Nicht zwingend. Die eben für komplexere Architekturen skizzierte 
selbstkalibrierende Variante verwendet als Iterationsschritt nicht "1", 
sondern beispielsweise "Nanosekunden pro Iteration". Da muss der 
Parameter "Wartezeit in Nanosekunden" nicht umgerechnet werden.

von Felix S. (fest)


Lesenswert?

A. K. schrieb:
> Felix Sturm schrieb:
>
>> Zeit = Zahl zwischen 260 und 10.000 => Sie ändert sich => Die Zeit muß
>> live berechnet werden.
>
> Nicht zwingend. Die eben für komplexere Architekturen skizzierte
> selbstkalibrierende Variante verwendet als Iterationsschritt nicht "1",
> sondern beispielsweise "Nanosekunden pro Iteration". Da muss der
> Parameter "Wartezeit in Nanosekunden" nicht umgerechnet werden.

Warum zeigst du nicht einfach ein Beispiel, das den Befehl in Assembler 
ersetzt?

von (prx) A. K. (prx)


Lesenswert?

Felix Sturm schrieb:

> Warum zeigst du nicht einfach ein Beispiel, das den Befehl in Assembler
> ersetzt?

Was ich hier skizziert habe ist ein Verfahren für Warteschleifen, dass 
ohne Taktzählung von Befehlssequenzen und ohne Umrechung des 
Zeitparameters auskommt. Ich habe das in etwas speziell geschriebenen 
C-Code für Cortexe implementiert, aber das Prinzip ist unabhängig davon 
- einzig ein Timer mit bekannter Zählfrequenz wird übergangsweise für 
die Kalibrierung benötigt.

Wenn du einen einzigen Assemblerbefehl suchst, der dir fix und fertig 
zwischen 260µs und 10ms wartet - den gibt es nicht. Architekturen mit 
explizitem Delay-Befehl sind selten, mir kommt da nur SC/MP in den Sinn.

Wenn es das nicht ist, dann versuch nochmal deutlich, dein Ziel zu 
erklären. Für fertigen PIC Assembler-Code bin ich freilich nicht 
zuständig, d.h. ich werde dir kein entsprechendes Programm(stück) 
schreiben.

von Felix Sturm (Gast)


Lesenswert?

A. K. schrieb:
> dein Ziel zu
> erklären.

Wie sieht ein Assemblercode für den PIC 16F628A aus, der genau diese
Operation ausführt?

------

Ist die Frage etwa "Wie sieht ein Assemblercode für den PIC 16F628A aus, 
der eine Sekunde bei 20 Mhz wartet?"

Dann ist die Antwort

Verzoegerung
      ;4999993 cycles
  movlw  0x2C
  movwf  d1
  movlw  0xE7
  movwf  d2
  movlw  0x0B
  movwf  d3
Verzoegerung_0
  decfsz  d1, f
  goto  $+2
  decfsz  d2, f
  goto  $+2
  decfsz  d3, f
  goto  Verzoegerung_0

      ;3 cycles
  goto  $+1
  nop

      ;4 cycles (including call)
  return

für 20Mhz.

Grüße

von Karl H. (kbuchegg)


Lesenswert?

Felix Sturm schrieb:


> Ist die Frage etwa "Wie sieht ein Assemblercode für den PIC 16F628A aus,
> der eine Sekunde bei 20 Mhz wartet?"
>
> Dann ist die Antwort

OK.
Wie ist der arithmetische Zusammenhang zwischen 4999993 und den 3 
Konstanten 0x2C, 0xE7 und 0x0B?

Du brauchst daher dann noch Baissroutinen für Addition, Subtraktion, 
Multiplikation und Division um diese, von dir festgestellte Formel zu 
berechnen (wobei natürlich nicht vergessen werden darrf, dass diese 
Berechnung dann auch Zeit benötigt). Damit berechnet man dann im Vorfeld 
die für die gewünschte Zeit benötigten Konstanten und lässt den 
untenstehenden Code dann mit den berechneten Werten ablaufen.

Ist eine Möglichkeit. Es gibt sicher noch andere. Zb kann man sich einen 
Standardschleifenaufsatz machen, der ziemlich genau 1 Millisekunde Zeit 
benötigt. Hat man dann die gewünschte Wartezeit in Millisekunden 
gegeben, dann ruft man in einer Schleife diese 1 Millisekunde-Wartezeit 
entsprechend oft auf und zählt dabei die Wartezeit jeweils um 1 runter. 
Ist man bei 0 angelangt, hat man entsprechend viele Schleifendurchläufe 
und ist fertig.


Aber allen gemeinsam ist: Es erfordert Basiskentnisse so etwas zu 
machen. Rechnen mit dem µC ist etwas, dass man können muss (und auch 
üben muss), wenn man einen µC programmiert. In einer Hochsprache wie C 
bringt der Compiler entsprechende Arithmetikroutinen mit, in Assembler 
muss man sich die selber machen (oder irgendwo klauen)

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.