Hallo, ich benutze Microcontroller, um damit Maschinensteuerungen zu
realisieren. Um das komplett in C zu machen, fehlt mir eine
Implementierung von Monoflops, die in Speicherprogrammierbaren
Steuerungen (SPS) unter dem Namen "Timer" kennt. Daher behelfe ich mir
bisher mit der grafischen Programmieroberfläche Parsic [1], wo es so
etwas schon gibt. Kennt jemand ein C-Programm(modul), indem etwa 100
solche Monoflops/Timer bereitgestellt werden?. Diese müssen auch
zeitlich überlappend laufen können. Daher funktioniert die
"delay"-Lösung nicht, die einfach nur eine No-Operation Warteschleife
produziert.
Ich weiß, dass man für die Lösung meines Problems Ticks zählen soll.
Aber ich habe noch keine funktionierende Implementation gesehen.
Die Timer, von denen ich hier spreche, sind nicht zu verwechseln mit dem
Hardware-"Timer" in Microcontrollern.
[1]
http://www.parsicitalia.it/development-tools-compilers-visual-parsic-v4.html
Eine normale SPS hat auch keine 100 Hardwaretimer.
Sowas wird in Software gelöst.
Bei einer SPS hat man ja meist eh eher langsame Timer.
Da benutzt du einen Hardwaretimer der z.B. einen 10ms oder 100ms Takt
erzeugt und damit läßt du deine Software Timer zählen.
Thomas der Bastler schrieb:> Gibt es für AVRs auch solche grafischen Programieroberfläche , wie das> erwähnte Parsic Programm ?
Ja: http://microsps.com/ Aber wieso man sich das antun will? In C ist es
doch viel komfortabler als mit diesen Klötzchen zu speilen.
Picer schrieb:> Eine normale SPS hat auch keine 100 Hardwaretimer.> Sowas wird in Software gelöst.
Genau diese Software suche ich.
> Bei einer SPS hat man ja meist eh eher langsame Timer.> Da benutzt du einen Hardwaretimer der z.B. einen 10ms oder 100ms Takt> erzeugt und damit läßt du deine Software Timer zählen.
Weiß ich, hatte ich oben schon beschrieben. Diesen 10ms oder 100ms Takt
nennt man Ticks. Obwohl dieser Lösungsansatz vielfach beschrieben wird,
habe ich noch keine funktionierende Implementation gesehen. Entweder
liegt der Teufel im Detail oder ich finde eine implementierte Lösung
einfach nicht. Kennt jemand eine solche?
Eric B. schrieb:> Einfache Implementierung mit Polling:// MODULE: SwTimer.c
Vielen Dank! Ich denke, ich verstehe. Man muss zudem noch dafür sorgen,
dass
currentTime = 0u
immer dann ausgeführt wird, wenn der Eingang des Monoflops gesetzt wird.
Nun muss aber für jedes neue Monoflop immer eine Menge Code ins Programm
eingefügt werden. Bei einer SPS geht das komfortabler, weil deutlich
kürzer. Gibt es auch unter C eine Möglichkeit, als Aufruf einfach nur zu
schreiben (oder ähnlich):
//verzögert monoflopinput{1) um 1000ms und schreibt das Ergebnis nach
monoflopoutput(1)
monoflopoutput(1,1000)
Sobald ich weitere Monoflops brauche, schreibe ich als Aufruf nur:
monoflopoutput(2,400)
monoflopoutput(3,80)
monoflopoutput(4,300)
....
monoflopinput(x) und monoflopoutput(x) seien dabei bool.
Baltar schrieb:> Man muss zudem noch dafür sorgen,> dass> currentTime = 0u> immer dann ausgeführt wird, wenn der Eingang des Monoflops gesetzt wird.
Nein, dass passt so.
> Nun muss aber für jedes neue Monoflop immer eine Menge Code ins Programm> eingefügt werden.
"eine Menge"? Drei Zeilen + dass was du machen willst wenn die Zeit
abgelaufen ist.
Eric B. schrieb:> Einfache Implementierung mit Polling:// MODULE: SwTimer.c> static uint32 currentTime = 0u;>> void SwTimerHandler(void)> {> // update every X ms> currentTime += X;> }>> uint32 SwTimerNow()> {> return currentTime;> }>> bool SwTimerPassed(uint32 timeStamp, uint32 delay)> {> return (currentTime - timeStamp) > delay;> }>> Benutzung:uint32 time;>> // get "now"> time = SwTimerNow();>> // check if 1000ms have passed since setting time> if(SwTimerPassed(time, 1000)> {> // Yes! At least 1000ms have passed> }> Jetzt kannst du so viele "Timer" aufsetzen wie an RAM zur Verfügung> steht :-)
O.K., offensichtlich verstehe ich das Programm doch nicht.
Möglicherweise fehlt mir die Kenntnis eines Konzeptes der Sprache C, das
zum Verständnis notwendig wäre.
Könnte mir jemand den genauen Ablauf mit zwei Sotwaretimern/Monoflops
erklären, die sich zeitlich überlappen? Sagen wir, der erste Timer
verzögert um 1000 msec und der zweite um 1200ms. Der Zufall will es,
dass der zweite Timer 400ms nach dem ersten gestartet wird. Dann hätten
wir eine zeitliche Überlappung.
Irgendwo muss es doch dann zwei bool Variable geben, welche die Eingänge
und zwei andere bool Variable, welche die Ausgänge darstellen. Im Code
erkenne ich als Ausgang "SwTimerPassed". Stimmt das? Aber wo ist der
Eingang?
Baltar schrieb:> Im Code erkenne ich als Ausgang "SwTimerPassed". Stimmt das?
Mit SwTimerPassed(time, 1000) kannst du abfragen, ob seit dem Zeitpunkt
time 1000 ms vergangen sind, gestartet wird das indem du time auf den
aktuelle Zeit setzt. Wenn es dir besser gefällt kannst du das auch noch
in eine Funktion packen.
O.T.
Thomas der Bastler frog:
> Gibt es für AVRs auch solche grafischen Programieroberfläche , wie das> erwähnte Parsic Programm ?
Great Cow Basic gibt es mit wahlweise grafischer Eingabe für AVR und PIChttp://gcbasic.sourceforge.net/
MfG Paul
Bin zwar kein Basic-Fan, aber das Ding kann ja zumindest Ausdrücke, die
komplexer sind als nur ein ASM-Statement. Noch weniger Grund die hier
gehätschelte Basic-Variante zu --kaufen-- .
Thomas Elger schrieb:
:u32
> monoflops[NUMBER_OF_MONOFLOPS];>> und zwei Funktionen:void set_timer(u8 select, u32 duration)> {> monoflops[select] = systemtime + duration;> }>> bool check_timer(u8 select)> {> if ((s32)(monoflops[select] - systemtime) <= 0)> return TRUE;> else> return FALSE;> }
Sieht ja schonmal deutlich übersichtlicher aus. Dennoch verstehe ich es
leider nicht. Wo wird denn der Variable "systemtime" ein Wert
zugeordnet?
Baltar schrieb:> Sieht ja schonmal deutlich übersichtlicher aus. Dennoch verstehe> ich es leider nicht. Wo wird denn der Variable "systemtime" ein> Wert zugeordnet?
In der natürlich notwendigen Interrupt-Routine des (Hardware-)Timers.
"systemtime" ist, wie der Name suggeriert, die Systemzeit, die also
z.B. jede Millisekunde um eins erhöht wird.
Possetitjel schrieb:>> Sieht ja schonmal deutlich übersichtlicher aus. Dennoch verstehe>> ich es leider nicht. Wo wird denn der Variable "systemtime" ein>> Wert zugeordnet?>> In der natürlich notwendigen Interrupt-Routine des (Hardware-)Timers.> "systemtime" ist, wie der Name suggeriert, die Systemzeit, die also> z.B. jede Millisekunde um eins erhöht wird.
O.K. verstanden. Mir war nicht klar, dass Systemzeit ein etablierter
Begriff ist. Er ist mir noch nie über den Weg gelaufen.
Korrekt - "systemtime" muss natürlich irgendwo extern auf dem Laufenden
gehalten werden (am Besten natürlich in einer ISR, ausser man hat den
Luxus eines entsprechenden Hardware-Systemtimers).
Vielleicht hätte ich noch anmerken sollen, daß der Code natürlich kein
komplettes, 1:1 verwendbares C-Programm sein soll, sondern nur zur
Verdeutlichung des Funktionsprinzips dienen soll. "bool" z.B. ist ja
auch kein Standard "C"-Datentyp, macht aber die Natur des Rückgabewertes
der Funktion (hoffentlich) einigermassen deutlich...
Thomas der Bastler schrieb:> Gibt es für AVRs auch solche grafischen Programieroberfläche , wie> das> erwähnte Parsic Programm ?
Das Einzigartige an Parsic ist, dass die im Funktionsschaltplan
vergebenen Namen für Eingänge und Ausgänge eines Funktionsblockes (z.B.
Zähler, Gatter, Monoflop etc) auch im "compilierten" Assemblerprogramm
diese Namen als Name der Speicherzelle im RAM behalten. Außerdem ist
derjenige Assemblercode, der einen Funktionsblock abarbeitet, mit dem
dafür im Funktionsschaltplan vergebenen Namen gekennzeichnet.
Das versetzt einen in die Lage, mit Hilfe einer Hardware (Microchip
ICD3) und PC-Software (Microchip MPLABX) während des Abarbeiten des
Programmes im Controller dieses live (auch im Einzelschritt) zu
verfolgen, in jede Variable hineinzusehen, ein Software-Oszilloskop
anzuschließen und vieles Andere mehr und so live zu debuggen. Ich habe
noch keine andere grafische Programmieroberfläche gesehen, die das
leistet. Von daher wäre Deine Frage aus meiner Sicht mit "Nein" zu
beantworten.