Mehr als 4 Timer realisieren

Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte

Elektronik Forum Nicht eingeloggt       Einloggen       Registrieren




[Registrieren]      --     [FAQ]      --     [ Einen Link auf Ihrer Homepage zum Forum]      --     [ Themen kostenlos per RSS in ihre Homepage einbauen]      --     [Einloggen]

Suchen


Serverzeit: 31 10 2024  00:26:53      TV   VCR Aufnahme   TFT   CRT-Monitor   Netzteile   LED-FAQ   Osziloskop-Schirmbilder            


Elektronik- und Elektroforum Forum Index   >>   Microcontroller        Microcontroller : Hardware - Software - Ideen - Projekte


Autor
Mehr als 4 Timer realisieren
Suche nach: timer (2124)

    







BID = 685310

gerhard54

Gelegenheitsposter



Beiträge: 76
Wohnort: Wien
 

  


Hallo

ich möchte folgende Funktion mit einem Atmega realisieren:

Nach dem Setzen eines Eingangs soll ein Ausgang für eine bestimmte Zeit (einige Sekunden) gesetzt und dann wieder gelöscht werden. Und zwar sollte diese Funktionalität für meher E/A-Paare gleichzeitig, aber mit unterschiedlichen Startzeiten möglich sein.

Ein Beispiel, mit einer Verzögerung von 5 Sekunden
Sekunde 1: Eingang 1 wird gesetzt, Ausgang 1 schaltet ein
Sekunde 2: Eingang 2 wird gesetzt, Ausgang 2 schaltet ein
Sekunde 6: Ausgang 1 schaltet ab
Sekunde 7: Ausgang 2 schaltet ab

Alles kein Problem, wenn nicht mehr E/A-Paare gleichzeitig aktiv sind, als der ATMEGA Timer hat. Es sollen aber mehr sein! Etwa 20, die EA's werden über einen Bus gesteuert...

Und jetzt meine Frage:
hat jemand schon einmal dieses Problem gelöst? Gibt's Code Schnipsel dafür?

Ich bin für jede Anregung dankbar, die es mir erspart die Sache von Grund auf zu programmieren.

Grüße
Gerhard

BID = 685315

Her Masters Voice

Inventar


Avatar auf
fremdem Server !
Hochladen oder
per Mail an Admin

Beiträge: 5308
Wohnort: irgendwo südlich von Berlin

 

  

da braucht man nur einen einzigen Timer. Der macht seine Interrupte in regelmässigen Intervallen und bei Jedem kann man eigene Zähler hochzählen wie man mag. Ausserhalb des Interrupts werden die Zähler dann ausgewertet und die entsprechenden Pins gesetzt oder gelöscht. Wo soll da das Problem sein?

_________________
Tschüüüüüüüs

Her Masters Voice
aka
Frank

***********************************
Der optimale Arbeitspunkt stellt sich bei minimaler Rauchentwicklung ein...
***********************************

BID = 685327

Nukeman

Schriftsteller



Beiträge: 754
Wohnort: bei Kleve

Ich lass für sowas aus nem Timer-Interrupt z.B. mit einer Schleife immer Elemente
aus einem Array bis 0 runterzählen. Nur wenn Array-Element noch nicht 0, wird eins
runtergetickt.
Der Vorteil ist dann, dass man

a) aus main() die Laufzeit individuell und variabel bestimmen kann
b) im Interrupt nicht auf bestimmte Werte checken muss, wenn untersch. Laufzeiten
gewünscht sind.

Gruß
Stefan


edit: Schleife, nicht Schleide ( bin froh, dass ich nicht noch einen Fehler mehr
in dem Wort untergebracht hatte )


[ Diese Nachricht wurde geändert von: Nukeman am 20 Apr 2010 22:58 ]

BID = 685328

gerhard54

Gelegenheitsposter



Beiträge: 76
Wohnort: Wien

Hallo,

ja so ungefähr hab' ich es mir auch vorgestellt.

NUR: "Hochzählen bei Interrupts verwalten" ist bei einer im vorhinein nicht bekannten Anzahl von Instanzen ist ein ziemlicher Programieraufwand, mit einer recht beachtlichen Möglichkeit Fehler zu machen...

Daher meine Frage: hat so etwas schon wer programmiert?

Wenn nicht, muß ich's eh selber machen.
Ich versuche mir einfach eine Menge Schreib- und Debugaufwand zu ersparen.

Also:
Wenn jemand ein bißchen Input spendet, verspreche ich, das Ergebnis hier zu veröffentlichen....

LG
Gerhard

BID = 685334

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika


Zitat :

einer im vorhinein nicht bekannten Anzahl von Instanzen ist ein ziemlicher Programieraufwand


Dann geh von der maximal möglichen Anzahl aus. Dann haste halt ein paar Byte RAM zuviel statisch alloziiert, wenn nicht alle genutzt werden.

Der Aufwand, vor allem an Rechen, RAM- und ROM-Ressourcen für eine dynamische Verwaltung ist auf nem Mega8 zu groß.


P.S.: in der ISR würde ich die Berechnungen nicht durchführen. Erstens, weil dann die Codegröße enorm hochgeht, zweitens weil es ein paar µs dauert und drittens weil die Zeitintervalle recht groß sind und so ein paar ms mehr oder weniger egal sind.

-> Flagge in der ISR setzten und im Hauptprogramm erledigen.

_________________

BID = 685335

gerhard54

Gelegenheitsposter



Beiträge: 76
Wohnort: Wien

Hallo Stefan,

Deine Antwort hat sich mit meiner auf die an "Her Masters Voice" gekreuzt.

Ein Array, in dem heruntergezählt wird: der Ansatz gefällt mir sehr gut!

Programmierst Du das "Hard Core" oder hast Du da Klassen definiert, die die Sache ein bißchen abstrahieren?

Ich träume von einer Lösung, wo man eine Instanz eines Timers erstellt und das Array und die Sache mit dem Herunterzählen wird vom Konstruktor erledigt...
In der main-Schleife frage ich dann ab, ob der Timer abgelaufen ist, während im Hintergrund der Destruktor aufräumt...


Grüße
Gerhard

BID = 685337

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

*Zonk*




Sowas kann man mit 20 Assemblerbefehlen erledigen (übern Daumen gepeilt) und du kommt mit C++...




_________________

BID = 685340

Nukeman

Schriftsteller



Beiträge: 754
Wohnort: bei Kleve

Hallo Gerhard,

soll's C, Bascom oder ASM sein?

Bei Timern im Sekundenbereich würde ich das sogar eher noch ohne Interrupts machen.
Timer-Überläufe (des Hardware-Timers) kann man dann auch in einer Hauptschleife
abfragen und somit trotzdem sehr genau bleiben.

Gruß
Stefan


Für c so in etwa:



Code :


char timer[20];

void main( void )
{
char x;

( hw-timer 0 entsprechend konfigurieren..)

while( 1) // hauptschleife
{

// Timer-Kram
if( (TIFR & (1<<TOV0)) ) // T0 ovfl?
{
TIFR |= (1<<TOV0); // T0-ovfl wieder löschen

for( x=0; x<sizeof(timer); x++ )
{
if( timer[x] )
{
if( --timer[x] == 0 )
{
( aktion fuer timer x ausführen )
}
} // timer noch aktiv
} // for
} // if




// externe Bedingung-Kram

if( externe Bedingung erfolgt )
{
timer[0] = 20; // Time
timer[1] = 4;
...
}

} // while
}



1.Huch, wird hier schnell gepostet, wenn man mal kurz Kram zusammenschreibt
2.Klammerfehler im Pseudocode




[ Diese Nachricht wurde geändert von: Nukeman am 20 Apr 2010 23:23 ]

BID = 685387

hajos118

Schreibmaschine



Beiträge: 2453
Wohnort: Untermaiselstein

1) Kann der WinAVR C - Compiler tatsächlich C++ ?
2) Wie groß wird der Code ?

Ich verwende ausschließlich Standard C - das genügt!
Zum Problem:
Array und dekrementieren - wegen Geschwindigkeit wenn möglich im 8-Bit Bereich bleiben ...

alternativ:
1 Zentraler Zähler (in ISR inkrementiert = "jetzt"), Timerwerte[x] beim setzten auf tick[x] = (jetzt + dauer) setzten und in der Hauptschleife mit
if "jetzt > tick[x]" abfragen.
Vorteil: nur 1 inkrement + 1 Abfrage pro Timer.
Achtung: hoher Aufwand bei Überlauf des "jetzt".

edit:
Wahrscheinlich kannst Du den einzelnen Aufgaben feste Indizes zuordnen - damit wird dann die Verwaltung der Unterroutinen einfacher.
z.B.
if jetzt > tick[1] work1();
if jetzt > tick[2] work2();
if jetzt > tick[3] work3();
if jetzt > tick[4] work4();
...



_________________
Interpunktion und Orthographie dieses Beitrags sind frei erfunden.
Eine Übereinstimmung mit aktuellen oder ehemaligen Regeln wäre rein zufällig und ist nicht beabsichtigt.
Wer einen Fehler findet, darf ihn behalten!

[ Diese Nachricht wurde geändert von: hajos118 am 21 Apr 2010 10:16 ]

BID = 685390

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Hallo Hajos,


Zitat :

1) Kann der WinAVR C - Compiler tatsächlich C++ ?
2) Wie groß wird der Code ?


zu 1:
Ja, kann er.
Das Backend bzw. den ganzen Toolchain-Rattenschwanz dafür kannst du, analog zum 'normalen' GCC C++-Backend (g++) mit avr-g++ aufrufen.
C++ wird allerdings nicht komplett unterstützt (kaum ein Compiler unterstützt alles, was C++ rein theoretisch können sollte... ).
Exceptions, new, new[], delete und delete[] sind nicht implementiert, wobei man sich letztere mit der libc zusammenbauen könnte, indem man new und delete überlädt und intern dann mit malloc und free arbeitet.
Weiterhin ist die STL und die STDC++ nicht vorhanden...
Die ist auch wesentlich größer als der ROM der kleineren AVRs und dafür auch schlicht und ergreifend nicht gemacht.
Achja, alle Arten von virtuellen Methoden/Konstruktoren etc. tunlichst vermeiden.
Auch RTTI und andere nette Dinge nicht verwenden. Braucht alles zuviel Ressourcen.

zu 2:
Ansich ist der Code recht gut, wobei er auch bei bester Optimierung auf Codegröße etwas größer wird. Das liegt vor allem daran, dass man in C++ gerne objektorientiert programmiert und in den Klassen permanent der this-Zeiger mitgeschleppt wird. Rein imperative Dinge wie in C gehen in C++ dann ähnlich flott.
Und wenn wirklich dynamische Speicherverwaltung über die libc genutzt wird, kannst du dich auf gigantische Codegröße einstellen...

Ansonsten habe ich einige, auch den Mega8 und Mega48 in C++ programmiert. Da ging es aber um "Luxus".
Es macht ein Programm schöner, wenn ich mit eigenen Datentypen auch eigene Operatoren einführen kann. Aber wie gesagt, alles zu lasten der Codegröße.

(Performant bleibt es dennoch, wenn man es ordentlich macht!)

Edit:

Zitat :

Ich verwende ausschließlich Standard C - das genügt!

Jau, sauberes C z.B. nach ansi ist eigentlich das beste.
Einige Programme laufen bei mir auf AVRs, ARMs, AVR32s und x86. Ohne eine Zeile am C-Kode zu ändern...

_________________


[ Diese Nachricht wurde geändert von: DonComi am 21 Apr 2010 10:49 ]

BID = 686232

gerhard54

Gelegenheitsposter



Beiträge: 76
Wohnort: Wien

Also einmal schönen Dank für die vielen Anregungen.

Nur der Vollständigkeit halber: eigentlich schreibe ich die meisten Programme in ANSI C. Ich versuch' nur seit 15 Jahren den Einstieg in C++ zu machen, und da habe ich mir gedacht: so eine Timer-Klasse wär doch was für den Angfang...

Liebe Grüße aus Wien

Gerhard

BID = 686254

DonComi

Inventar



Beiträge: 8605
Wohnort: Amerika

Hallo Gerhard,

ist auch machbar. Ich habe aber leider nichts passendes zur Hand.
Bei einer Sekunde Intervall kommt es nicht auf ein paar ms an, die ein C++-Handler benötigt.


Ich hätte da sogar was im Kopf, aber ich habe keine Zeit.
Dazu zählt eine abstrakte Timerklasse, an die man Funktionen über deren Adresse anhängen kann. Läuft die Zeit der entsprechenden Methode/Funktion ab, wird sie aufgerufen.


Man kann es aber ganz schön kompliziert machen...

_________________

BID = 687090

gerhard54

Gelegenheitsposter



Beiträge: 76
Wohnort: Wien

Natürlich kann man es nicht nur, sondern man sollte es auch... sonst machts ja keinen Spaß.

Gerhard


Zurück zur Seite 1 im Unterforum          Vorheriges Thema Nächstes Thema 


Zum Ersatzteileshop


Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum       Datenschutz       Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland       

gerechnet auf die letzten 30 Tage haben wir 24 Beiträge im Durchschnitt pro Tag       heute wurden bisher 0 Beiträge verfasst
© x sparkkelsputz        Besucher : 182260150   Heute : 42    Gestern : 4669    Online : 657        31.10.2024    0:26
0 Besucher in den letzten 60 Sekunden         ---- logout ----viewtopic ---- logout ----
xcvb ycvb
0.063108921051