Forum: Mikrocontroller und Digitale Elektronik Timer Compare Match läuft nicht an


von Timmy (Gast)


Lesenswert?

Hallo,

ich habe ein kleines Problem.
Prozessor Atmega8
Funktion: Frequenzmessung mit Input Capture, ab einer bestimmten 
Frequenz, soll eine LED leuchten und nach einer halben Periodenlänge 
wieder ausgeschaltet werden (durch das zuvor berechnete Compare Match).
Die eigentliche Messung habe ich mal rausgeschmissen, die funktioniert. 
Die LED geht auch bei einer eingetellten Grenzfrequenz an, jedoch geht 
diese nicht mehr aus.
Ausgeschaltet wird sie im Compare Match A des Timers1. Daher vermute ich 
den Fehler entweder beim Initialisieren des Compare Matches (was ich 
mittlerweile 5x mit dem Datenblatt gecheckt habe) oder beim berechnen 
des Compare Match Wertes und/oder dem casten der verschiedenen 
Datentypen.
1
#include <stdint.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <inttypes.h>
5
6
#ifndef F_CPU
7
#define F_CPU           8000000UL                   // processor clock frequency 8Mhz
8
#endif
9
10
#define PrescalerTC1 64
11
12
#define Input    PB0    //Pin des Input Captures PB0=ICP
13
#define LED      PB1    
14
#define LED1    PB2    
15
16
17
#ifndef TRUE
18
#define TRUE 1
19
#define FALSE 0
20
#endif
21
22
// ----------------------------------------------------------------------------
23
// Variabeln Interrupt
24
// ----------------------------------------------------------------------------
25
volatile unsigned char NrOverflowsTC1 = 0;    //Overflows TC1
26
                      
27
volatile unsigned int StartZeit= 0;        // Wert 1.Flanke
28
volatile unsigned int EndZeit = 0;        // Wert 2. Flanke
29
volatile double Gesamtzeit = 0.0;        // enthält die Gesamtzeit in Taktzyklen 
30
volatile unsigned char Grenze=50;        // Grenzfrequenz
31
volatile unsigned long Frequenz=0;        // enthält die Frequenz
32
volatile unsigned char NrOverflowsCompareTC1 = 0; // Anzahl Overflows bis zum Compare Match A
33
34
35
ISR( TIMER1_CAPT_vect ){
36
/*hier erfolgt zuvor eine Frequenzberechnung
37
Programm wurde gekürzt
38
*/
39
  Gesamtzeit = (NrOverflowsTC1 * 65536) + Endzeit - StartZeit ;//Zeit in Taktzyklen
40
      Frequenz = (F_CPU/PrescalerTC1)/Gesamtzeit;   // Zeit in Hz      
41
      if (Frequenz>=Grenze){
42
        Gesamtzeit = Gesamtzeit/2;      // halbe Zeit in Taktzyklen
43
        NrOverflowsCompareTC1 = Gesamtzeit/65536;  // Anzahl overflows (ganzzahlig, da char, Overflows sind immer kleiner als 256)
44
        OCR1A = TCNT1+Gesamtzeit;      // Compare Match Register, Anzahl OVF bereits berücksichtigt
45
                          // da unsigned gerechnet wird, spielen Überläufe keine Rolle, es kommt der richtige Wert heraus
46
        TIMSK |= (1 << OCIE1A);      // Compare Match Interrupt aktivieren
47
        PORTB &= ~(1 << LED1);        // LED anschlaten
48
      }
49
50
ISR (TIMER1_OVF_vect){
51
  NrOverflowsTC1++;                  // Overflows zur Frequenzmessung
52
  if (NrOverflowsCompareTC1){             // wenn TRUE und damit ungleich 0
53
    NrOverflowsCompareTC1--;            // NrOverflowsCompareTC1 dekrementieren bis es 0 --> dann wird erst Aufgabe im Compare Match ausgeführt
54
  }
55
56
}
57
58
ISR (TIMER1_COMPA_vect){
59
  if (!NrOverflowsCompareTC1){          // wenn Wert !FALSE und damit gleich 0
60
  TIMSK &= ~(1 << OCIE1A);              // Compare Match Interrupt deaktivieren (wird erst wieder in ISR ICP aktiviert, wenn nötig)
61
  PORTB |= (1 << LED1);                // LED ausschalten
62
  }
63
}
64
65
//Hauptprogramm
66
int main()
67
{
68
69
  DDRB = 0x00;                    //alle Eingang 
70
  DDRB |= (1 << DDB1) | (1 << DDB2);         //PB2 Ausgang(LED)
71
  PORTB |= (1 << Input) | (1 << LED1);        //Pullup Input Capture, LED ausschalten
72
           
73
  TCCR1B = (1 << CS00) | (1 << CS01) | (1 << ICNC1);  // Prescaler 64, Noise Cancellor
74
  TCCR1B &= ~(1<<ICES1);                  // IC fallende Flanke
75
  TIMSK = (1<<TICIE1) | (1<<TOIE1);             // IC, Timer OVF enable
76
  TCCR1A &= ~ ((1 << COM1A0) | (1 << COM1A1));      // Timer1 16-bit Compare Match eingestellt
77
  
78
  
79
  while(1){
80
    
81
    if (NrOverflowsTC1 >= 250){                    //sichert, dass der Datentyp char des OverflowTC1 nicht überläuft
82
      NrOverflowsTC1 = 0;
83
    }
84
  }
85
}

Sieht jemand einen möglichen Fehler?

von Justus S. (jussa)


Lesenswert?

Interrupts sind nicht aktiviert

von Timmy (Gast)


Lesenswert?

Sorry, mein Fehler. Die sind aktiviert.
Habe sei(); drin, nur ob bei der Frequenzberechnung durch das löschen 
wohl mit rausgehopst.

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.