www.mikrocontroller.net

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


Autor: Timmy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>

#ifndef F_CPU
#define F_CPU           8000000UL                   // processor clock frequency 8Mhz
#endif

#define PrescalerTC1 64

#define Input    PB0    //Pin des Input Captures PB0=ICP
#define LED      PB1    
#define LED1    PB2    


#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif

// ----------------------------------------------------------------------------
// Variabeln Interrupt
// ----------------------------------------------------------------------------
volatile unsigned char NrOverflowsTC1 = 0;    //Overflows TC1
                      
volatile unsigned int StartZeit= 0;        // Wert 1.Flanke
volatile unsigned int EndZeit = 0;        // Wert 2. Flanke
volatile double Gesamtzeit = 0.0;        // enthält die Gesamtzeit in Taktzyklen 
volatile unsigned char Grenze=50;        // Grenzfrequenz
volatile unsigned long Frequenz=0;        // enthält die Frequenz
volatile unsigned char NrOverflowsCompareTC1 = 0; // Anzahl Overflows bis zum Compare Match A


ISR( TIMER1_CAPT_vect ){
/*hier erfolgt zuvor eine Frequenzberechnung
Programm wurde gekürzt
*/
  Gesamtzeit = (NrOverflowsTC1 * 65536) + Endzeit - StartZeit ;//Zeit in Taktzyklen
      Frequenz = (F_CPU/PrescalerTC1)/Gesamtzeit;   // Zeit in Hz      
      if (Frequenz>=Grenze){
        Gesamtzeit = Gesamtzeit/2;      // halbe Zeit in Taktzyklen
        NrOverflowsCompareTC1 = Gesamtzeit/65536;  // Anzahl overflows (ganzzahlig, da char, Overflows sind immer kleiner als 256)
        OCR1A = TCNT1+Gesamtzeit;      // Compare Match Register, Anzahl OVF bereits berücksichtigt
                          // da unsigned gerechnet wird, spielen Überläufe keine Rolle, es kommt der richtige Wert heraus
        TIMSK |= (1 << OCIE1A);      // Compare Match Interrupt aktivieren
        PORTB &= ~(1 << LED1);        // LED anschlaten
      }

ISR (TIMER1_OVF_vect){
  NrOverflowsTC1++;                  // Overflows zur Frequenzmessung
  if (NrOverflowsCompareTC1){             // wenn TRUE und damit ungleich 0
    NrOverflowsCompareTC1--;            // NrOverflowsCompareTC1 dekrementieren bis es 0 --> dann wird erst Aufgabe im Compare Match ausgeführt
  }

}

ISR (TIMER1_COMPA_vect){
  if (!NrOverflowsCompareTC1){          // wenn Wert !FALSE und damit gleich 0
  TIMSK &= ~(1 << OCIE1A);              // Compare Match Interrupt deaktivieren (wird erst wieder in ISR ICP aktiviert, wenn nötig)
  PORTB |= (1 << LED1);                // LED ausschalten
  }
}

//Hauptprogramm
int main()
{

  DDRB = 0x00;                    //alle Eingang 
  DDRB |= (1 << DDB1) | (1 << DDB2);         //PB2 Ausgang(LED)
  PORTB |= (1 << Input) | (1 << LED1);        //Pullup Input Capture, LED ausschalten
           
  TCCR1B = (1 << CS00) | (1 << CS01) | (1 << ICNC1);  // Prescaler 64, Noise Cancellor
  TCCR1B &= ~(1<<ICES1);                  // IC fallende Flanke
  TIMSK = (1<<TICIE1) | (1<<TOIE1);             // IC, Timer OVF enable
  TCCR1A &= ~ ((1 << COM1A0) | (1 << COM1A1));      // Timer1 16-bit Compare Match eingestellt
  
  
  while(1){
    
    if (NrOverflowsTC1 >= 250){                    //sichert, dass der Datentyp char des OverflowTC1 nicht überläuft
      NrOverflowsTC1 = 0;
    }
  }
}

Sieht jemand einen möglichen Fehler?

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interrupts sind nicht aktiviert

Autor: Timmy (Gast)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.