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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von TU Student 1. (student0)


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


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


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


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


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


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


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


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


Bewertung
-1 lesenswert
nicht lesenswert
Einfach BASCOM nehmen. Da hat es eine WAITMS Funktion.


Example
WAITMS 10  'wait for 10 mS

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


Bewertung
0 lesenswert
nicht 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. (Firma: Albert-Ludwigs-Universität) (pkk)


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

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]
  • [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.