mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mehrere Aufgaben abarbeiten


Autor: mike32m (Gast)
Datum:

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

Autor: Pepe (Gast)
Datum:

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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Patrick Weinberger (seennoob)
Datum:

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

Autor: aha (Gast)
Datum:

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

Autor: Patrick Weinberger (seennoob)
Datum:

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

Autor: peterguy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
 void Funktionsname (void); 

Auf diesen Funktionstyp wird ein Funktionspointer definiert:
 typedef void (*pFunc)( void ); 

Der Stapel sieht so aus (hier als Ringpuffer der Größe 20 
implementiert):
 struct {
  uint8 writeIndex;
  uint8 readIndex;
  pFunc job[20]; 
}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:
 
// adds function to the end of the list
int OS_AddJobToList( pFunc function ); 

// gets next job from list. returns a NULL pointer if list is empty
pFunc OS_GetNextJobFromList( ); 

Hier die Funktion, welche die Liste abarbeitet:
 void OS_Dispatcher( void ) 
{
  pFunc function;
  
  // try to get next job
  function = OS_GetNextJobFromList( );
  
  // Check if new job is available
  if (function == NULL) {
    return;  
  }
     // execute job
  (function)();
  
  return; 
} 

Diese Dispatcher Funktion wird so im Hauptprogram aufgerufen:
void main (void)
{ 
   InitAll();
   while(1)
   {
      OS_Dispatcher();
   }
}

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.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Multitasking

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.