www.mikrocontroller.net

Forum: Compiler & IDEs Warum hat Timer Einfluss auf Kommunikation ?


Autor: Andreas P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo alle zusammen,
ich stehe mal wieder vor einem eigenartigen Problem!
Ich habe einen Atmel AT90CAN128 und sende damit LIN und CAN Nachrichten.
Die LIN Nachrichten "sollen" mittels eines Timers 
(ISR(TIMER0_COMP_vect)) der auf 100kHz eingestellt ist, alle 10ms eine 
LIN Botschaft versenden.
Wenn ich jetzt LIN Nachrichten versende MIT dem Timer, bekomme ich nur 
Errorflags. Wenn ich den Timer ausschalte und dann nochmal Nachrichten 
sende, bekomme ich alles richtig raus.
Bei CAN ist es egal ob Timer an oder aus, da kommt immer alles korrekt 
raus.

Meine Frage jetzt:
Kann es sein das der Timer soviel Reccoursen benötigt, das meine LIN 
Nachrichten nicht mehr sauber versendet werden können ?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas P. schrieb:
> Kann es sein das der Timer soviel Reccoursen benötigt

Was erwartest Du denn bei wahnsinns 10µs Interruptrate?
Rechne mal nach, wie wenig CPU-Zyklen das sind.

Dem CAN macht das nichts, da er das Protokoll komplett in Hardware 
macht.

So als Faustregel, ein Interrupt sollte nicht schneller als alle 500 
Zyklen aufgerufen werden.

Wenn Du 10ms brauchst, nimm auch nen 10ms Interrupt.


Peter

Autor: Andreas P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt auch mal auf dem UART geschaut was dort ankommt.
Also die Daten kommen richtig am UART an!

@Peter:
Ich habe einen "Vergleichstimer", der wie folgt aufgebaut ist:
Ich habe eine 8MHz CLK, daher lasse ich den Timer bis 80 Zählen, dann 
soll in Interrupt ausgelöst werden (also 8MHz/80Schritte = 100kHz)
Ich kann aber max. bis 255 Schritte vergleichen, daher funktioniert 
deine Idee mit dem "alle 10ms" ausführen leider nicht.
Da ich den Counter auch noch für andere Zwecke nutzen möchte, muss 
dieser min. alle 1ms ausgelöst werden.

Wie kann ich den Counter "langsamer" machen, so das meine Reccursen 
nicht so ausgelastet werden.

void init_timer()
{
  hundert_taus_sek=0;
  zehn_taus_sek=0;
  millisekunden=0;
  hundert_sek=0;
  zehntel_sek=0;
  sekunde=0;

  TCCR0A =(1<<WGM01)|(1<<CS00); // CTC-> Clear Timer on Comparematch, Prescaler off
  OCR0A= 0x50; //bis 80 Zählen   ->100kHz (8MHz CLK)
  

    TIMSK0 |= (1<<OCIE0A);  //Compare Interrupt aktivieren
}


ISR(TIMER0_COMP_vect)
{
  hundert_taus_sek++;
  if(hundert_taus_sek==10)
  {
    zehn_taus_sek++;
    hundert_taus_sek=0;

    if( delay_count > 0 )  // Nachrichtenverzögerung (1/10ms)
    {
      delay_count--;
    }

    if(zehn_taus_sek==10)
    {
      PORTA ^= (1<<PA0);  //**********DEBUGG LED********+
      millisekunden++;

      zehn_taus_sek=0;
      if(millisekunden==10)
      {
        millisekunden=0;
        hundert_sek++;
        PORTA ^= (1<<PA2);  //**********DEBUGG LED********+
        if(hundert_sek==10)
        {
          hundert_sek=0;
          zehntel_sek++;
          PORTA ^= (1<<PA4);  //**********DEBUGG LED********+
          if(zehntel_sek==10)
          {
            zehntel_sek=0;
            sekunde++;
            PORTA ^= (1<<PA6);  //**********DEBUGG LED********+

            trigger_time++;
            if(sekunde == 43200) //12 Stunden
            {
              modus=3;
              new_file=1;
              sekunde=0;
              trigger_time=0;
            }
          }
        }
      }
    }
  }
}



Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas P. schrieb:

> Ich habe eine 8MHz CLK, daher lasse ich den Timer bis 80 Zählen, dann
> soll in Interrupt ausgelöst werden (also 8MHz/80Schritte = 100kHz)

80 Schritte ist schon verdammt wenig.
Das sind ungefähr 60 Assemblerinstruktionen. Davon gehen bei C schon mal 
gut und gerne 20 bis 30 für die ISR Preämbel/Ausstieg drauf, so dass 
kaum mehr was übrig bleibt. Für die ISR. Aber auch das Hauptprogramm 
muss ja auch noch arbeiten.

> Ich kann aber max. bis 255 Schritte vergleichen, daher funktioniert
> deine Idee mit dem "alle 10ms" ausführen leider nicht.

Du hast ja auch noch einen Vorteiler.

> Da ich den Counter auch noch für andere Zwecke nutzen möchte, muss
> dieser min. alle 1ms ausgelöst werden.

100kHz sind aber auch keine 1ms

Autor: Andreas P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Karl heinz,

ich habe den Vorteiler ganz überlesen... habe jetzt einen Vorteiler von 
8 genommen --> 1MHz und lasse bis 100Schritte zählen was dann eine 
Interruptauslösung von 10kHz ergibt.
Jetzt funktioniert auch das versenden von LIN Nachrichten mit 
eingeschaltenem Timer !
TCCR0A =(1<<WGM01)|(1<<CS01); // CTC-> Clear Timer on Comparematch, Prescaler 8 ---> 8.000.000 / 8 = 1MHz
OCR0A= 0x64; //bis 100 Zählen   ->10kHz (8MHz CLK)


Ich werde die Auslösezeit trotzdem noch runterschrauben um auf der 
sicheren Seite zu sein.

!!!!!!! DANKE MAL WIEDER FÜR EURE HILFE !!!!!!!!!!!

Gruß Andreas P.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas P. schrieb:

> Ich werde die Auslösezeit trotzdem noch runterschrauben um auf der
> sicheren Seite zu sein.

Und noch was.
Kein Mensch sagt, dass du die ISR in 10-er Bruchteilen aufrufen musst.
Da du dann sowieso noch einen Software-Teiler hinten nachschaltest, 
kannst du anstelle von alle 100-Timer Schritte ja auch alle 200 Timer 
Schritte die ISR auslösen lassen.
In der ISR zählst du dann eben nicht bis 100 sondern nur bis 50 um die 
weiteren Aktionen auslösen zu lassen und hast dann für die 
Aktionsauslösung immer noch dasselbe Timing. Aber mit nur der Hälfte der 
ISR Aufrufe.

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.