Forum: Mikrocontroller und Digitale Elektronik Delay-Routine für STM8S


von TU Student 1. (student0)


Lesenswert?

Hat jemand eine funktionierende ms-Delay-Routine ohne Timer für den 
STM8S unter SDCC?

Derzeit nutze ich:
1
static inline void delay(unsigned int t)
2
{
3
    while (t--)
4
        ;
5
}
6
7
static inline void delay_us(unsigned int t)  //Ungenau
8
{
9
    delay(t*4);
10
}
11
  
12
static inline void delay_ms(unsigned int t)  //Ungenau
13
{
14
    delay_us(t*1000);
15
}

Das funktioniert, ist aber nicht zyklengenau, da ich das ungefähr diesem 
Inline-ASM-Beispiel nachempfunden ist:
https://github.com/Hoksmur/stm8_routines/blob/master/delay.h

Mir kommt es so vor, wie wenn der SDCC etwas wegoptimieren würde bzw. 
sich undefiniert verhält - teilweise Fehlermeldungen auftreten, je 
nachdem ob die Funktion "inline" ist.

von Route_66 H. (route_66)


Lesenswert?

TU S. schrieb:
> eine funktionierende ms-Delay-Routine ohne Timer

Das ist sowas, wie eine schwangere Jungfrau: das Eine schließt das 
Andere aus.

von Rechen Knecht (Gast)


Lesenswert?

Route 6. schrieb:
> das Eine schließt das Andere aus.

Man muss nur den Kreis quatratisch machen.

von Axel S. (a-za-z0-9)


Lesenswert?

Zeitverzögerung mit busy waiting kann man machen. Aber natürlich muß man 
dann die Taktfrequenz berücksichtigen und die innere Schleife schreibt 
man besser in inline Assembler, damit es unabhängig vom Compiler wird. 
Für kurze Delays (wenige µs) sollte es dann besser ein Makro sein. Schau 
dir die delay-Funktionen aus der AVR-libc an. Die funktionieren, also 
kann das Design nicht ganz falsch sein.

von Volle22 (Gast)


Lesenswert?

Axel S. schrieb:
> Zeitverzögerung mit busy waiting kann man machen.

machen aber nur Anfänger die das auch bleiben wollen.
Es ist die schlechteste aller Möglichkeiten.

von TU Student 1. (student0)


Lesenswert?

Volle22 schrieb:
> Axel S. schrieb:
>> Zeitverzögerung mit busy waiting kann man machen.
>
> machen aber nur Anfänger die das auch bleiben wollen.
> Es ist die schlechteste aller Möglichkeiten.

Bei einer Display-Initialisierung oder anderen "Blocking" Tasks ist das 
durchaus legitim, deswegen frage ich ja auch.    Mit nem Timer kann ich 
es auch, keine Frage ;)

Eigentlich könnte ich es auch bei der Initialisierung nutzen, denn da 
brauche ich den Timer sowieso (noch) nicht für andere Tasks.

Die Frage ist jedoch von ganz allgemeinem Interesse: Wie mache ich 
später, bei anderen Programmen kurze Delays (us-Bereich), z.b. wenn ich 
VGA/Video-Timings erzeuge?   Genau da nutzt man üblicherweise 
Busy-Waiting-Delays.

Axel S. schrieb:
> Zeitverzögerung mit busy waiting kann man machen. Aber natürlich
> muß man
> dann die Taktfrequenz berücksichtigen und die innere Schleife schreibt
> man besser in inline Assembler, damit es unabhängig vom Compiler wird.
> Für kurze Delays (wenige µs) sollte es dann besser ein Makro sein. Schau
> dir die delay-Funktionen aus der AVR-libc an. Die funktionieren, also
> kann das Design nicht ganz falsch sein.

Du meinst, die gesamte innere Schleife? Also auch mit bedingtem Sprung, 
usw..?

Das wäre eine Idee, wenn der Compiler dann von der Optimierung dieses 
Inline-ASM Teils absehen würde.   SDCC unterstützt auch eine "Peephole 
ASM" Optimierung - ob der Inline-Teil dann unangetastet bleibt, weiss 
ich nicht.   Alle bisherigen Beispiele hatten als Inline-ASM nur "NOP", 
der Rest war in C.

In ASM ist es machbar, allerdings kenne ich mich mit der 
STM8-Architektur nicht gut genug aus, ich weiss nicht, wie sich die 
Pipeline, Wait sates etc... auswirken um das zyklengenau zu bekommen. 
Einzige Alternative wäre an einem Portpin zu messen - ich würde es aber 
gerne verstehen. Beim PIC ist es einfach: 4 Quarztakte normal, 4*2 
Quarztakte bei Sprung

Im STM8 CPU Manual sieht man die Problematik:
http://www.st.com/content/ccc/resource/technical/document/programming_manual/43/24/13/9a/89/df/45/ed/CD00161709.pdf/files/CD00161709.pdf/jcr:content/translations/en.CD00161709.pdf

Die Zyklenzahl hängt ab ob aus dem Flash/RAM abgearbeitet wird, sie 
hängt von der Länge des Instruction Words ab (Prefetch-Buffer 96 Bit) 
usw...  - es ist also relativ komplex, ähnlich wie bei 16/32-Bittern.

: Bearbeitet durch User
von Volle22 (Gast)


Lesenswert?

du bekommst nie ein zuverlässiges Timing
es mag jetzt meist funktionieren ( weil du nicht siehst das es nur 99.8% 
sind)

Dann ändert jemand eine Interrupt Routine, baut irgendwo noch was ein , 
schliest den Debugger an, nimmt ein neuere Version des Prozessors, 
ändert einen Einstellung ...
schon bist du bei 95%
es fällt auf
und du suchst tagelang nach dem Problem

von Rechen Knecht (Gast)


Lesenswert?

Also beim STM32F1xx ode F4xx zählt man mit der

  --> Data Watchpoint and Trace Unit

die Zyklen und kann damit ziemlich präzise auf die Mikrosekunden
zurückrechnen.

Ob es das beim 8-Bitter auch gibt hab ich jetzt nicht nachgeschaut.

von P. Loetmichel (Gast)


Lesenswert?

Einfach BASCOM nehmen. Da hat es eine WAITMS Funktion.


Example
WAITMS 10  'wait for 10 mS

von Axel S. (a-za-z0-9)


Lesenswert?

Volle22 schrieb:
> Axel S. schrieb:
>> Zeitverzögerung mit busy waiting kann man machen.
>
> machen aber nur Anfänger die das auch bleiben wollen.
> Es ist die schlechteste aller Möglichkeiten.

Das hängt wesentlich davon ab, wie lange man warten muß. Wenn man z.B. 
ein paar µs bei der Ansteuerung von Peripherie warten muß (z.B. einem 
HD44780 LCD) dann ist busy waiting das Mittel der Wahl.


TU S. schrieb:
>> die innere Schleife schreibt
>> man besser in inline Assembler, damit es unabhängig vom Compiler wird

> Du meinst, die gesamte innere Schleife? Also auch mit bedingtem Sprung,
> usw..?

Ja.

> Das wäre eine Idee, wenn der Compiler dann von der Optimierung dieses
> Inline-ASM Teils absehen würde.

Mir wäre nicht bekannt, daß ein C-Compiler Inline-ASM anfassen würde. 
Wäre auch verfehlt, IMHO. Im Notfall implementierst du die Funktion in 
reinem Assembler.

von Philipp Klaus K. (pkk)


Lesenswert?

TU S. schrieb:
> Das wäre eine Idee, wenn der Compiler dann von der Optimierung dieses
> Inline-ASM Teils absehen würde.   SDCC unterstützt auch eine "Peephole
> ASM" Optimierung - ob der Inline-Teil dann unangetastet bleibt, weiss
> ich nicht.   Alle bisherigen Beispiele hatten als Inline-ASM nur "NOP",
> der Rest war in C.

Inline-ASM fasst der Peephole Optimizer nur an, wenn die Option 
--peep-asm verwendet wird.

Philipp

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.