Forum: Mikrocontroller und Digitale Elektronik taskmanager mit definierter zeit funktioniert nicht


von marcel (Gast)


Lesenswert?

hi,

ich hab mit meinen kollege ein "taskmanager" erstellt

der soll alle 20ms abgearbeitet werden und wenn er länger als 20 ms 
braucht soll eine LED aufleuchten.

das problem ist das selbst wenn wir alles auskommentiert haben oder die 
tasks leer lassen die 20ms anscheinend überschritten werden.


TCCR2A = (1<<WGM21) |(0<<WGM20) | (0<<COM2A1) | (1<<COM2A0) | (1<<CS22) 
| (1<<CS21) | (1<<CS20) ;

OCR2A= 76;


int task_state = 0;
 uint8_t Led_status=0;

 while (1)
{

  {
//*********** Taskmanager alle 20ms***************************  ocr2a >> 
"75"
    switch (task_state)
    {
      case (0):
      {


      }
      break;

      case (1):
      {

      }
      break;

      case (2):
      {

      }
      break;

      case (3):
      {

      }
      break;

      case (4):
      {

      }
      break;

      default:
      {

      }
      break;

    }

    if (task_state == 4)
    {
      task_state = 0;
    }
    else
    {
      task_state ++;
    }

    if (bit_is_set(TIFR2,OCF2A))
    {

    PORTB |= (1<<PB4);
      //FEHLER: Task Dauert zu lang!

    }

    while (bit_is_clear(TIFR2,OCF2A)) // Warte bis Timer Compare Match 
Flag gesetzt ist
    {
              //irgendwas unkritisches tun (idle-Task)
    }
    TIFR2 |= (1<<OCF2A);          //Timer Compare Match Flag rücksetzen


  }

}

return 0;
}

von Guido S. (flintstone)


Lesenswert?

marcel schrieb:
>     TIFR2 |= (1<<OCF2A);          //Timer Compare Match Flag rücksetzen

Diese Zeile ist im Hauptprogramm unsinnig. Abgesehen davon, dass der 
Kommentar nicht stimmt. Das Bit wird hiermit gesetzt.

Dieses Bit wird von der Hardware gesteuert. Das ist noch nicht die 
Lösung deines Problems. An dieser Stelle kannst du weitersuchen.

Gruß
Guido

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

1
          // irgendwas unkritisches tun (idle-Task)
Und der Timer läuft so lange weiter...

Guido Scheidat schrieb:
>>     TIFR2 |= (1<<OCF2A);      //Timer Compare Match Flag rücksetzen
> Diese Zeile ist im Hauptprogramm unsinnig. Abgesehen davon, dass der
> Kommentar nicht stimmt. Das Bit wird hiermit gesetzt.
Alle 3 Behauptungen sind falsch. Das solltest du nochmal genauer 
nachlesen...

von Guido S. (flintstone)


Lesenswert?

OK, ich werde lesen.

Sprechen wir vielleicht von verschiedenen Prozessoren?

Sorry!

von marcel (Gast)


Lesenswert?

im handbuch steht

"Alternatively, OCF2A is cleared by writing a logic
one to the flag."

von marcel (Gast)


Lesenswert?

es geht um den at90can128

von VAR (Gast)


Lesenswert?

Guido Scheidat schrieb:
>>     TIFR2 |= (1<<OCF2A);          //Timer Compare Match Flag rücksetzen
>
> Diese Zeile ist im Hauptprogramm unsinnig. Abgesehen davon, dass der
> Kommentar nicht stimmt. Das Bit wird hiermit gesetzt.

naja, irgendwer muß ja OCF2A wieder zurücksetzen, wenn da kein Interrupt 
ist der das üblicherweise tun würde

von Krapao (Gast)


Lesenswert?

>>     TIFR2 |= (1<<OCF2A);          //Timer Compare Match Flag rücksetzen

> "Alternatively, OCF2A is cleared by writing a logic
> one to the flag."

Und wenn es im TIFR2 weitere solche Flags gibt, die man benutzt, darf 
man keine ODER Operation benutzen! Mit dem ODER löscht man nämlich 
auch die anderen gesetzten Flags! Richtig ist, wenn überhaupt: TIFR2 = 
(1<<OCF2A)

von marcel (Gast)


Lesenswert?

TIFR2 |= (1<<OCF2A);  //Timer Compare Match Flag rücksetzen


eigentlich bräuchte ich diesen aufruf doch gar nicht, wenn alles läuft 
muss doch gar kein interrupt aufgerufen werden

ich brauch doch nur wenn die zeit überlaufen wird, was mit (if bit is 
set) ja abgefragt wird, eine meldung.


hab jetzt mal ein anderen Port benutzt

komischerweise treten jetzt keine fehler mehr auf was bei Portb 4 noch 
der fall war

von Guido S. (flintstone)


Lesenswert?

Irgendwie haben sich hier viele Missverständnisse eingeschlichen.

ich habe jetzt gelesen und bin auf folgende Info gestoßen:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ver.C3.A4ndern_von_Registerinhalten
somit wird mit "TIFR2 |= (1<<OCF2A);" ein Bit gesetzt.

Jetzt zum Vorhaben. Ich hatte ganz übersehen, dass es sich nicht um ein 
interruptgesteuertes Programm handelt.
Ist es wirklich so, dass OCF2A durch die Hardware zurückgesetzt wird, 
wenn die Zeit abgelaufen ist? Passiert das auch, wenn man keine 
Interrupts verwendet? Kann das jemand mal mit AVR-Studio testen? Ich 
habe gerade keines zur Hand.

von Krapao (Gast)


Lesenswert?

@ Guido

> ich habe jetzt gelesen und bin auf folgende Info gestoßen:
> http://www.mikrocontroller.net/articles/AVR-GCC-Tu...
> somit wird mit "TIFR2 |= (1<<OCF2A);" ein Bit gesetzt.

Das ist richtig für normale Variablen und SFRs.

>> "Alternatively, OCF2A is cleared by writing a logic
>> one to the flag."

Genau da geht es aber nicht mit dem ODER!

Bsp:

TIFR2 = 0b10000001;

Du willst Bit0 löschen

TIFR2 |= 0b00000001;

Dann ist anschliessend

TIFR2 gleich 0b00000000 !!!
               ^      ^

Wieso?

TIFR2 |= 0b00000001;

Ist eine Kombination aus (volatile Charakter von TIFR2 mal aussen vor)

1) TIFR2 einlesen
2) eingelesenes TIFR2 mit 0b00000001 verodern
3) Ergebnis in TIFR2 schreiben

Der Haken ist Schritt 2:
0b10000001 | 0b00000001 = 0b10000001

Und dann die Zuweisung
TIFR2 = 0b10000001

Damit ist Bit0 und Bit7 gelöscht, wenn Bit0 und Bit7 solche 
Spezialbits sind, die durch Beschreiben mit 'ner log. 1 gelöscht werden!

von Karl H. (kbuchegg)


Lesenswert?

Krapao schrieb:

> Genau da geht es aber nicht mit dem ODER!

völlig richtige Analyse.

Ergänzend:
Genau das ist nämlich auch der Grund, warum diese Register sich anders 
verhalten: Damit man eben NICHT erst das Register auslesen, den Wert 
verodern und neu schreiben muss. Denn diese 3-er Kombination ist nicht 
atomar, was man aber beim Löschen derartiger Bits sein möchte. D.h. man 
WILL eine Operation haben, die garantiert in einem Ausführungszyklus 
dieses Bit und nur dieses Bit löscht.

: Wiederhergestellt durch User
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
Noch kein Account? Hier anmelden.