www.mikrocontroller.net

Forum: Compiler & IDEs Tiemer Polling wird nur einmal erkannt


Autor: Norbert S. (norton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe folgendes Problem: Wenn ich einen Timer Starte und mittels 
polling versuche eine SW PWM zu machen erkenne ich nur beim ersten mal 
das Timer Interrupt Flag.
Was habe ich bei dem Code falsch gemacht?
void mv1_ein()                                    
{                                              
  // Timer initialisieren
  power_timer3_enable();
  TCNT3  = 0x00;                      // Zähler Register auf 0 setzen
  OCR3A  = 450;                      // Verhältnis einstellen
  OCR3B  = m_pwm_wert;                  // Verhältnis einstellen

  TCCR3A  = (1<<WGM31) | (1<<WGM30);
  TCCR3B  = (1<<WGM33) | (1<<WGM32) | (1<<CS30);      // Fast PWM

  m_timer_stop_counter = 0;
  m_timer_stoped = 0;
  
  TIFR3 = 1<<TOV3;
  TIFR3 = 1<<OCF3B;

  while (!m_timer_stoped)                                
  {      
    if (!(TIFR3 & (1<<TOV3)))
    {
      TIFR3 = 1<<TOV3;

      PORTA &= ~ (1<<measureT);
      uart_send_u16(0);

      m_timer_stop_counter++;
      if (m_timer_stop_counter >= 132)          // Impulsende
      {
        TCCR3B |= (1<<CS30) | (1<<CS31) | (1<<CS32);  // Timer abschalten
        power_timer3_disable();
        m_timer_stop_counter = 0;
        m_timer_stoped = 1;
      }
    }

    if (!(TIFR3& (1<<OCF3B)))
    {

      TIFR3 = 1<<OCF3B;
      PORTA |= (1<<measureT);
      uart_send_u16(1);
    }
    //uart_send_u16(2);
  }                                          
}                          

Habe ich bei der Abfrage etwas falsch gemacht?

Gruß Norton

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Codefetzen ist nicht ausreichend, um das Problem eindeutig zu lösen.

Was passiert sein kann ist, dass der Timer überhaupt nicht angeschaltet 
ist. In dem Fall läuft das *while (!m_timer_stoped)* so lange bis *if 
(m_timer_stop_counter >= 132)* erfüllt ist.

Wie geschrieben, kann man das nicht eindeutig beurteilen, weil die 
Definition der Schlüsselvariablen (m_timer_stop_counter, m_timer_stoped, 
volatile notwendig?) und des Timerinterrupts nicht angegeben ist und der 
grundsätzliche Aufbau von main unbekannt ist. Und weil nicht klar ist, 
wie der Timer3 eineschaltet wird, denn die Definition von 
power_timer3_enable() fehlt. IMHO würde ich auch ein 
power_timer3_enable() nicht vor den Initialisierungszuweisungen 
schreiben bzw. die Zuweisungen würde ich in der Funktion machen. Dito 
für power_timer3_disable().

Autor: Norbert S. (norton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan "stefb" B. wrote:
> Der Codefetzen ist nicht ausreichend, um das Problem eindeutig zu lösen.
>
> Was passiert sein kann ist, dass der Timer überhaupt nicht angeschaltet
> ist. In dem Fall läuft das *while (!m_timer_stoped)* so lange bis *if
> (m_timer_stop_counter >= 132)* erfüllt ist.

Das Problem ist daß er nur einmal in "if (!(TIFR3 & (1<<TOV3)))" 
reinkommt, und nie bis 132 kommt.


> Wie geschrieben, kann man das nicht eindeutig beurteilen, weil die
> Definition der Schlüsselvariablen (m_timer_stop_counter, m_timer_stoped,
> volatile notwendig?) und des Timerinterrupts nicht angegeben ist und der
> grundsätzliche Aufbau von main unbekannt ist.

alle "m_..." Variablen sind volatile.
es soll kein (ISR) Timerinterrupt geben sondern nur das polling!
im main wird die Funktion "mv1_ein();" aufgerufen

> Und weil nicht klar ist,
> wie der Timer3 eineschaltet wird, denn die Definition von
> power_timer3_enable() fehlt.

die definition ist in der avr-libc und schaltet die versorgung des 
Timers ein
eingeschaltet wird der Timer mit "TCCR3B  = (1<<WGM33) | (1<<WGM32) | 
(1<<CS30);      // Fast PWM"

> IMHO würde ich auch ein
> power_timer3_enable() nicht vor den Initialisierungszuweisungen
> schreiben bzw. die Zuweisungen würde ich in der Funktion machen. Dito
> für power_timer3_disable().

Ich verstehe leider nicht was du damit meinst.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Timer3-Interrupt läuft also nicht (da das global interrupt enable 
mittels sei(), die Interrupt-Routine und - ungeprüft eventuell mehr - 
fehlen) und du fragst in dem if (!(TIFR3 & (1<<TOV3))) nur den 
Startzustand der Timer3-Hardware ab, die dann mit der Anweisung TIFR3 = 
1<<TOV3; von dir geändert wird und so den nächsten Aufruf des if-Falls 
verhindert...

Autor: Norbert S. (norton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan "stefb" B. wrote:
> Dein Timer3-Interrupt läuft also nicht (da das /global interrupt enable/
> mittels sei(), die Interrupt-Routine und - ungeprüft eventuell mehr -
> fehlen) und du fragst in dem if (!(TIFR3 & (1<<TOV3))) nur den
> Startzustand der Timer3-Hardware ab, die dann mit der Anweisung TIFR3 =
> 1<<TOV3; von dir geändert wird und so den nächsten Aufruf des if-Falls
> verhindert...

eigentlich sollte doch mit "TIFR3 = 1<<TOV3;" das Bit gelöscht werden? 
Oder?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gelöscht oder getoggelt? Um es genau zu sagen, müsste ich im Datenblatt 
nachsehen. Um welchen µC geht es genau?

Ich habe bei diesem "Polling" Bauchweh. Warum machst du das nicht 
klassisch mit einem laufenden Timer3?

IMHO bringt es nichts, die Timerhardware zu initialisieren, dann aber 
nicht zu starten und dann abzufragen, ob der Timer3 was gemacht hat.

Autor: Norbert S. (norton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es handelt sich um einen ATmega1281

in den klasischen Interrupts ist zuviel overhead drin (ist mir zulangsam 
bei nur ganz kleiner ausschaltzeit)

Autor: fabi1973 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Du möchtest das Timer Int-Flag pollen ohne einen Interrupt zu haben?
Wichtig ist dass dann auf keinen Fall eine ISR aktiviert wird!

Ich verstehe nicht warum du erst abfrägst ob das Bit NICHT gesetzt ist 
um anschließend das Bit zu löschen?
Muss es nicht heissen:
if((TIFR3 & (1<<TOV3)) ....  // Wenn Flag gesetzt...
{
  lösche TOV3 durch schreiben einer 1..?
...

Oder hab ich da was komplett falsch verstanden?

Gruß

Fabian

Autor: Norbert S. (norton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich verstehe nicht warum du erst abfrägst ob das Bit NICHT gesetzt ist
> um anschließend das Bit zu löschen?
> Muss es nicht heissen:
> if((TIFR3 & (1<<TOV3)) ....  // Wenn Flag gesetzt...

Danke das war es.

So was blödes, Da hab ich immer wieder drübergelesen.

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.