Tiemer Polling wird nur einmal erkannt

OP #987066
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?
1
void mv1_ein()                                    
2
{                                              
3
  // Timer initialisieren
4
  power_timer3_enable();
5
  TCNT3  = 0x00;                      // Zähler Register auf 0 setzen
6
  OCR3A  = 450;                      // Verhältnis einstellen
7
  OCR3B  = m_pwm_wert;                  // Verhältnis einstellen
8

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

12
  m_timer_stop_counter = 0;
13
  m_timer_stoped = 0;
14
  
15
  TIFR3 = 1<<TOV3;
16
  TIFR3 = 1<<OCF3B;
17

18
  while (!m_timer_stoped)                                
19
  {      
20
    if (!(TIFR3 & (1<<TOV3)))
21
    {
22
      TIFR3 = 1<<TOV3;
23

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

27
      m_timer_stop_counter++;
28
      if (m_timer_stop_counter >= 132)          // Impulsende
29
      {
30
        TCCR3B |= (1<<CS30) | (1<<CS31) | (1<<CS32);  // Timer abschalten
31
        power_timer3_disable();
32
        m_timer_stop_counter = 0;
33
        m_timer_stoped = 1;
34
      }
35
    }
36

37
    if (!(TIFR3& (1<<OCF3B)))
38
    {
39

40
      TIFR3 = 1<<OCF3B;
41
      PORTA |= (1<<measureT);
42
      uart_send_u16(1);
43
    }
44
    //uart_send_u16(2);
45
  }                                          
46
}

Habe ich bei der Abfrage etwas falsch gemacht?

Gruß Norton
Persönliche Seite #987093
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().
OP #987162
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.
Persönliche Seite #987180
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...
OP #987192
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?
Persönliche Seite #987205
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.
Gast #987236
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
OP #987845
> 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

Eine eigene Frage? Dieser Thread ist über 18 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.