Pulspause mit ATMega 8 messen

Gast #2189184
Lesenswert?
• ▲
▼
Hallo Leute,

ich will mit einem ATMega 8 die Länge einer Pulspause messen.
Mein Signal ist ein Rechtecksignal mit variabler Frequenz und variablem 
Tastverhältnis, von diesem Signal möchte ich die Aus-Zeit messen.

Ich habe mir schon etliche Beiträge zu diesem Thema durchgelesen, nur 
jetzt komme ich nicht mehr weiter, ich mache wahrscheinlich einen 
Denkfehler.

Ich gehe jetzt so vor, dass ich den ICP-Pin des Controllers nehme dort 
erst bei fallender Flanke einen Interrupt auslöse, in der 
Interruptschleife dann auf steigende Flanke umschalte und dann wiederum 
auf die positive Flanke warte.

Die beiden Timerstände zieh ich dann von einander ab und hab die 
Differenzzeit, das mache ich aus dem Grund, da ich ja den Anfangsstand 
des Timers nicht kenne wenn ich nur auf die steigende Flanke triggere.

Hinzu kommt, dass ich einen kleinen Überschwinger von maximal etwa 60ms 
nach jeder positiven Flanke habe, jetzt hab ich den Verdacht, dass hier 
schon die fallende Flanke erkannt wird, lange bevor sie wirklich kommt.

Hier der relevante Code:
1
//Timer 1 initalisieren  
2

3
  TCCR1B |= /*(1 << ICES1) | */(1 << CS11) | (1 << ICNC1);    //Input Capture auf Positive Flanke / Prescaler = 8 -> Timerfrequenz = 1MHz / Input Noise-Canceler An
4
  TIMSK |= (1 << TICIE1) | (1 << TOIE1);    //Input Capture Interrupt und Timer Overflow Interrupt aktivieren
5

6
//Pulspause berechnen
7

8
unsigned long get_timer()
9
{
10
  timer_value = valueB - valueA + (overflow * 65536);
11
  return timer_value;
12
}
13

14

15
ISR(TIMER1_CAPT_vect)
16
{
17

18

19
  if(run)
20
  {
21
  
22
    valueA  = ICR1;  // Inhalt vom Input Capture Register in Value A laden
23
    run = 0;
24
    overflow = 0;  // Overflow zurücksetzen
25
    TCNT1 = 0;   // Timerstand auf 0 setzen
26
    TCCR1B |= (1 << ICES1);  // Auf steigende Flanke triggern
27
    TIFR |= ( 1 << ICF1 );  //Input Capture Interrupt Flag löschen
28

29
  }
30

31
  else if (run == 0)
32
  {
33

34
    valueB = ICR1;  // Inhalt vom Input Capture Register in Value B laden
35
    run = 1;
36
    TCCR1B &= ~(1 << ICES1);  // Auf negative Flanke triggern
37
    TIFR |= ( 1 << ICF1 );  // Input Capture Interrupt Flag löschen
38
    overflow = 0;  //Overflow zurücksetzen
39
    
40
  }
41

42
}

Kann das überhaupt so funktionieren?

Die nächste Frage wäre, wie bekomme ich es hin, dass der Interrupt für 
die fallende Flanke für 60ms nach der steigenden Flanke unterdrückt 
wird? Ich habe es schon über Timer 2 probiert, aber das funktioniert 
auch nicht wirklich.

Ich hoffe Jemand kann mir weiterhelfen.

Danke!

Gruß, Kai
Angehängte Dateien:
Gast #2189209
Lesenswert?
• ▲
▼
1) Die Variablen in der ISR und im nicht sichtbaren Anwendungscode 
benutzten valueA, valueB, overflow und möglicherweise sollten volatile 
definiert sein. Sind sie das?

2) Toggele doch mal in der ISR(TIMER1_CAPT_vect) einen Pin am µC und 
beobachte das am Oszi. Dann siehst du wie der µC bzw. dein Programm das 
Eingangssignal erkennt.
Gast #2189217
Lesenswert?
• ▲
▼
Wieso nicht ein Timer?
Starten bei negativer Flanke,Stoppen bei positiver Flanke.
Starten und Stoppen im gleichen Interrupt.

Dann weist Du direkt die Low-Time und kannst über die bekannte Frequenz 
das Pwm-Verhältnis ausrechnen.

Gruß
Gast #2189237
Lesenswert?
• ▲
▼
Atmega8 Datenblatt Timer/Counter Interrupt Flag Register – TIFR

ICF1 is automatically cleared when the Input Capture Interrupt Vector is 
executed. Alternatively, ICF1 can be cleared by writing a logic one to 
its bit location.

TOV1 is automatically cleared when the Timer/Counter1 Overflow Interrupt 
Vector is executed. Alternatively, TOV1 can be cleared by writing a 
logic one to its bit location.

Angenommen die Hardware setzt in TIFR die Bits TOV1 und ICF1 und ICP-Irq 
kommt zuerst. Verodert man TIFR dann mit Bit ICF1 (Schreiben von 1 auf 
ICF1 = Löschen), verodert man gleichzeitig das bereits vorhandene 1 Bit 
TOV1 auf Bitposition TOV1, d.h. man hat beim Verodern ungewollt TOV1 
gelöscht. Eine Zeitmessung mit Overflow ist damit nicht sinnvoll 
möglich.

Das steht aber auch im Tutorial als typ. Fallstrick bei den AVR 
Interrupts.
Gast #2190101
Lesenswert?
• ▲
▼
Danke für eure Antworten,

die entsprechenden Variablen sind alle volatile.

Auf die Idee den einen Pin togglen zu lassen bin ich noch gar nicht 
gekommen, das werde ich mal ausprobieren.

@NopNop

Kann ich denn den Timer 1 so einfach starten und stoppen in der IC-ISR?
Der Input Capture gehört ja quasi zum Timer 1.

Wenn das so funktioniert dann wäre meine Idee, erst auf die fallende 
Flanke zu triggern und dann auf die steigende, also diese Umschaltung in 
der ISR selbst zu machen, prinzipiell in Ordnung oder?

Ich werde erstmal austesten ob das Signal überhaupt richtig erkannt 
wird.
#2190301
Lesenswert?
• ▲
▼
Kai schrieb:
> Kann ich denn den Timer 1 so einfach starten und stoppen in der IC-ISR?

Jain, Du holst Dir damit nen Jitter rein durch die unbekannte 
Interruptlatenz und den Startcode des Interrupthandlers.
Der Vorteil des Input Capture (zyklusgenau messen) wird damit 
vernichtet.

Solange keine 2 Überläufe stattfinden, ist die Differenz zweier 
Capturewerte immer richtig.


Peter
Gast #2198274
Lesenswert?
• ▲
▼
Ich hab es jetzt getestet, die Interrupts werden richtig ausgelöst.
Ich starte nun in der ersten Interruptschleife den Timer 1 und stoppe 
ihn in der 2. wieder,
das funktioniert nun auch super, mit ausreichender Genauigkeit.

Danke für Eure Hilfe!

Kai

Antwort schreiben

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.

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.