Tiemer Polling wird nur einmal erkannt

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren