Ich erarbeite gerade ein Projekt, bei dem ein ATmega32 mehrere Aufgaben übernehmen soll: - Temperatur im zeitl. Rhythmus ermitteln (1-Wire DS1820) (- Luftfeuchte ebendso ermitteln (später auch andere Sensoren)) - LED schalten (später Verbraucher) wenn Befehl via RFM12 erhalten - Tastaturmatrix auslesen (i2C) - eingegebene und gemessene Daten auf LCD darstellen (2-Wire) - eingegebene und gemessene Daten via RFM12 senden - Anfragen via RFM12 entgegennehmen und verarbeiten (Befehle) Hat jemand schon sowas aufgebaut und kann mir Tips geben, wie diese Aufgaben sinnvoll verteilt/organisiert werden sollten. Da hier verschiedene Module zusammenkommen, die mit unterschiedlichen Interrupts arbeiten, ist es für mich momentan ein wenig chaotisch und ich würde dies gern in geordnete Bahnen bringen. Danke für Anregungen zur Herangehensweise. Gruß Mike
Hallo, hab ne ähnliche Geschichte am Laufen. Hab folgenden Ansatz verfolgt: - Endlosschleife, die auf entsprechende Flags im Speicher reagiert: if (mLCDNeuerWert) { zeigeWertAn } if (...) { macheDenNächstenJob } - Die Flags werden rein durch die INTs gesetzt. - Möglichst nur INT-basiert arbeiten: z.B. USART Ausgabe komplett über INTs die Zeichen in den Puffer eintragen, wenn der Puffer leer ist; - Tätigkeiten anstossen ( z.B. Befehl über USART rausschicken ) auf die Antwort per INT warten. Eintragen der Antwortzeichen in Puffer und wenn alle Zeichen empfangen ( =EOT ), dann Flag in Variable setzen, um darauf in der Hauptschleife reagieren. Sorry, hab nur USART gearbeitet. Hoffe Dir trotzdem geholfen zu haben. Gruß, Pepe
Ok Ich würd an erster Stelle mal die Aufgaben analysieren und dann ordnen wie wichtig eine Aufgabe ist. Danach die Priorität für die Interruptsfestlegen. MFG
>Danach die Priorität für die Interrupts festlegen.
Mega32. Kann das nicht. Muss er auch nicht. Die Aufgaben sind ja alle
eher langsamer Art. Wie der erste Poste meinte : Den ADC und das UART im
Interrupt laufen lassen und alles im Main mit einem Timer und Flags
koordinieren.
Naja wennst jetzt Daten vom RFM Modul bekommst kann das blöd laufen wenn du nebenbei etwas anderes abarbeitest. Denn dann kann es dir dein Timming zusammenhauen ! Also würd ich da unter anderem wenn zB daten Empfangen oder Gesandet werden einfach mal die interrupts ausschalten (bis auf die Timerinterupts) MFG
Ich verwende für solche Aufgaben immer ein selbstentworfenes Stapelverarbeitungssystem. Der Grundgedanke dabei ist, daß Funktionen auf einen Stapel gelegt werden können und von dort schnellstmöglich abgearbeitet werden. Damit eine Funktion auf den Stapel gelegt werden kann muss sie folgenden Funktionsprototyp verwenden:
1 | void Funktionsname (void); |
Auf diesen Funktionstyp wird ein Funktionspointer definiert:
1 | typedef void (*pFunc)( void ); |
Der Stapel sieht so aus (hier als Ringpuffer der Größe 20 implementiert):
1 | struct { |
2 | uint8 writeIndex; |
3 | uint8 readIndex; |
4 | pFunc job[20]; |
5 | }OS_JobList; |
Dann gibt es zwei Funktionen für Zugriffe auf den Stapel. Hier aus Gründen der Übersichtlichkeit nur die Prototypen, bei Interesse kann ich auch die kompletten Funktionen posten:
1 | |
2 | // adds function to the end of the list
|
3 | int OS_AddJobToList( pFunc function ); |
4 | |
5 | // gets next job from list. returns a NULL pointer if list is empty
|
6 | pFunc OS_GetNextJobFromList( ); |
Hier die Funktion, welche die Liste abarbeitet:
1 | void OS_Dispatcher( void ) |
2 | {
|
3 | pFunc function; |
4 | |
5 | // try to get next job
|
6 | function = OS_GetNextJobFromList( ); |
7 | |
8 | // Check if new job is available
|
9 | if (function == NULL) { |
10 | return; |
11 | }
|
12 | // execute job
|
13 | (function)(); |
14 | |
15 | return; |
16 | }
|
Diese Dispatcher Funktion wird so im Hauptprogram aufgerufen:
1 | void main (void) |
2 | {
|
3 | InitAll(); |
4 | while(1) |
5 | {
|
6 | OS_Dispatcher(); |
7 | }
|
8 | }
|
Der Code ist sehr schlank und sehr effektiv. Wenn man möchte kann man den Code noch um einen Scheduler erweitern, der dann auf Basis eines Timerinterrupts in festen Zeitabständen Funktionen auf den Stapel legt. Ich kann auch hier gerne Beispielcode posten, nur ist der leider Hardwareabhängig und auf Freescale S12X MCUs ausgelegt.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.