Forum: Compiler & IDEs Tiemer Polling wird nur einmal erkannt


von Norbert S. (norton)


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?
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

von Stefan B. (stefan) Benutzerseite


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().

von Norbert S. (norton)


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.

von Stefan B. (stefan) Benutzerseite


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...

von Norbert S. (norton)


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?

von Stefan B. (stefan) Benutzerseite


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.

von Norbert S. (norton)


Lesenswert?

es handelt sich um einen ATmega1281

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

von fabi1973 (Gast)


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

von Norbert S. (norton)


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.

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.