- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 6 von 6

Thema: Timer0 + Timer1 Input Capture

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.09.2005
    Beiträge
    114

    Timer0 + Timer1 Input Capture

    Anzeige

    Praxistest und DIY Projekte
    An T1=PB1 wird ein Rechtecksignal mit variabler Frequenz angelegt.
    Diese kann man mit Timer1 zählen.

    Erzeugen Sie dann eine Torzeit mit Timer0 im CTC-Modus welche kleiner als 1 Sekunde sein soll.
    Dann verbinden Sie OC0=PB3 mit ICP1=PD6, um am Ende der Torzeit automatisch einen Input Capture den momentanen Stand von Timer1 auszulesen [...]


    Leider habe ich ein wenig Probleme mit der Aufgabenstellung.

    So wie ich das verstanden habe muss ich folgendes tun:

    1. Irgendwie PB1 verarbeiten. Ich denke hiermit ist nicht soetwas gemeint?!
    Code:
    while(PINB&_BV(1));
    freq++;
    while(!(PINB&_BV(1)));
    2. Mit Timer0 in bestimmten Zeitabständen (kleiner als 1 Sekunde) OC0 toggeln.
    Code:
        OCR0=180;        // 1/20
        TCNT0=0;
        TCCR0=(1<<WGM01)|(1<<CS12)|(1<<CS00)|(1<<COM00);    // CTC, pr=1024, bei Match OC0 toggle
    Warum 180?
    Nun.. Da es ja ein 8bit-Register ist kann ich nicht höher als 256 gehen.
    Und in der Aufgabenstelung ist von kleiner als 1 Sekunde die Rede
    Also habe ich hier 20hz.



    3. Da OC0 mit ICP1 verbunden ist kann ich den "Input Capture" Modus vom Timer1 verwenden.

    Code:
    // Timer 1
    TCNT1=0;
    TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS12)|(1<<CS10)|(1<<ICNC1)|(1<<ICES1);
    CTC wenn externes Signal, steigende Flanke und Noice-Canceler einschalten.



    Sooooo.

    das ganze sieht dann folgendermaßen aus (Punkt2 und 3. Punkt1 weiß ich noch nicht wie ich es implementieren soll )

    Code:
    #define SYSTEMCLOCK 3686400
    #define F_CPU 3686400UL    
    #define LCD_PORT PORTC
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include "display.inc"
    
    volatile unsigned long freq = 0;
    volatile unsigned int tim0_cnt = 0;
    
    int main(void){
        DDRC=0xff;
        DDRB=0xff;
        
        lcd_init();
        
        PORTB=0xff;
        
        lcd_setcursor(0,0);
        lcd_putstring("Freq: ");
        
        OCR0=180;        // 1/20
        TCNT0=0;
        TCCR0=(1<<WGM01)|(1<<CS12)|(1<<CS00)|(1<<COM00);    // CTC, pr=1024, bei Match OC0 toggle
        
    
        // Timer 1
        TCNT1=0;
        TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS12)|(1<<CS10)|(1<<ICNC1)|(1<<ICES1);
    
        
        TIMSK=(1<<OCIE0);
        
        TIFR=(1<<ICF1);
    
        
        while(1){
    
                
            if((TIFR&_BV(ICF1))!=0){
    
                TIFR=(1<<ICF1);
                
                lcd_setcursor(6,0);
                lcd_putdez_uint(ICR1);
                
            }
        }
        
        return 0;    
    }


    Problem
    Ich glaube er kommt nichtmal in die If-Schleife (innerhalb der While) rein

    Besten Dank
    Kesandal

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Code:
    TCCR1B=(1<<WGM13)|(1<<WGM12)|(1<<CS12)|(1<<CS10)|(1<<ICNC1)|(1<<ICES1);
    Wie soll denn bitte das Input-Capturing funktionieren, wenn du einen Timer-Mode auswählst, bei dem ICR1 anderweitig verwendet wird? Wieso überhaupt einen CTC-Mode?

    Und wieso wählst du als Clock-Source clkIO/1024? Das passt doch überhaupt nicht hierzu:
    An T1=PB1 wird ein Rechtecksignal mit variabler Frequenz angelegt.
    Diese kann man mit Timer1 zählen.

    Und so nebenbei:
    Ich glaube er kommt nichtmal in die If-Schleife (innerhalb der While) rein
    http://www.if-schleife.de/
    MfG
    Stefan

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.09.2005
    Beiträge
    114
    Hallo sternst,

    danke für Deine Antwort.

    Wie soll denn bitte das Input-Capturing funktionieren, wenn du einen Timer-Mode auswählst, bei dem ICR1 anderweitig verwendet wird? Wieso überhaupt einen CTC-Mode?
    CTC zu nehmen war meine Idee, weil ich ja später anhand vom Zählerstand die Frequenz ausgeben möchte.

    When a capture is triggered, the 16-bit value of the counter (TCNT1) is written to the Input Capture Register (ICR1). The Input Capture Flag (ICF1) is set at
    the same system clock as the TCNT1 value is copied into ICR1 Register
    Wird nach dem kopieren TCNT1=0 gesetzt?
    Das geht hierraus leider nicht hervor. Wenn dies der Fall ist, brauche ich natürlich keinen CTC.

    Und wieso wählst du als Clock-Source clkIO/1024? Das passt doch überhaupt nicht hierzu:
    weil:
    das ganze sieht dann folgendermaßen aus (Punkt2 und 3. Punkt1 weiß ich noch nicht wie ich es implementieren soll )
    Ich verstehe immernoch Deine Idee nicht eine externe Clok-Source zu wählen.
    Kannst Du mir vielleicht die Idee näher erleutern?
    Geändert von Kesandal (01.07.2011 um 23:41 Uhr)

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    CTC zu nehmen war meine Idee, weil ich ja später anhand vom Zählerstand die Frequenz ausgeben möchte.
    Und wo ist da der Zusammenhang zwischen "später anhand vom Zählerstand die Frequenz ausgeben" und CTC-Mode?


    Wird nach dem kopieren TCNT1=0 gesetzt?
    Nein.


    Wenn dies der Fall ist, brauche ich natürlich keinen CTC.
    Auch so kannst du mit dem CTC-Mode nichts anfangen. Jetzt verstehe ich aber, was dein Gedanke hinter der Mode-Wahl war. Kurz gesagt: das klappt nicht.
    Wenn es eine einmalige Messung ist, setzt du den Timer einfach "von Hand" auf Null. Und wenn es eine fortlaufende Messung sein soll, setzt du den Timer gar nicht auf Null, sondern ziehst die jeweiligen ge-capture-ten Timer-Werte voneinander ab.


    Ich verstehe immernoch Deine Idee nicht eine externe Clok-Source zu wählen.
    Das ist nicht meine Idee, sondern die Vorgabe der Aufgabe:
    An T1=PB1 wird ein Rechtecksignal mit variabler Frequenz angelegt.
    Diese kann man mit Timer1 zählen.
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    17.09.2005
    Beiträge
    114
    Ich habe nun den Quelltext entsprechend angepasst:

    Code:
    #define SYSTEMCLOCK 3686400
    #define F_CPU 3686400UL    
    #define LCD_PORT PORTC
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include "display.inc"
    
    volatile unsigned long freq = 0;
    volatile unsigned int tim0_cnt = 0;
    
    int main(void){
        DDRC=0xff;
        DDRB=0xff;
        
        lcd_init();
        
        PORTB=0xff;
        
        lcd_setcursor(0,0);
        lcd_putstring("Freq: ");
        
        OCR0=180;        // 1/20
        TCNT0=0;
        TCCR0=(1<<WGM01)|(1<<CS12)|(1<<CS00)|(1<<COM00);    // CTC, pr=1024, bei Match OC0 toggle
        
    
        // Timer 1
        TCNT1=0;
        TCCR1B=(1<<CS12)|(1<<CS11)|(1<<CS10)|(1<<ICNC1)|(1<<ICES1);
    
        
        TIMSK=(1<<OCIE0);
        
        TIFR=(1<<ICF1);
    
        
        while(1){
    
                
            if((TIFR&_BV(ICF1))!=0){
    
                TIFR=(1<<ICF1);
                
                lcd_setcursor(6,0);
                lcd_putdez_uint(ICR1);
                TCNT1=0;
                
            }
        }
        
        return 0;    
    }
    Irgnedwie scheint das mit Clock-Source = extern nicht zu klappen.
    Im Display erhalte ich nämlich nur die ausgabe: Freq: 0000

    Gibt es noch etwas bei der externen Clock-Source zu beachten?
    Laut Manual müsste es ja reichen wenn ich die Bits im TCCR1B entsprechend setze.

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Gibt es noch etwas bei der externen Clock-Source zu beachten?
    Dein Programm verursacht an dem Pin einen Kurzschluss. Das dürfte hinderlich sein.

    Außerdem hast du die beiden oben erwähnten Möglichkeiten vermengt. Du hast eine fortlaufende Messung, setzt den Counter aber auf Null. Das ergibt ungenaue Ergebnisse, zumal du das Zurücksetzen auch noch an der ungünstigsten Stelle überhaupt platziert hast.
    MfG
    Stefan

Ähnliche Themen

  1. Timer1 - Clear Timer on Input-Capture?
    Von Tyrald im Forum C - Programmierung (GCC u.a.)
    Antworten: 20
    Letzter Beitrag: 14.08.2010, 20:39
  2. TIMER1 CAPTURE INPUT
    Von Koertis im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 14.08.2010, 13:39
  3. Input-Capture am AT90S8515?
    Von eIdea im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 15.05.2006, 20:11
  4. atmega32 - Timer1 - Capture Interrupt
    Von Jeluca im Forum AVR Hardwarethemen
    Antworten: 4
    Letzter Beitrag: 27.02.2006, 20:00
  5. Timer1 Capture im BASCOM Simulator
    Von Werner_Just im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 17.02.2005, 10:52

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests