- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 7 von 7

Thema: Problem mit Timer

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Benutzer Stammmitglied
    Registriert seit
    08.03.2010
    Beiträge
    66

    Problem mit Timer

    Hallo,

    ich habe probiert einen Timer zu verwenden. Allerdings wird er nie aktiviert.

    Code:
    void Timer0_init(void)
    {
       TCCR0A =  (1<<WGM01);                        // Timer im CTC-Modus
       TCCR0A |= (1<<CS02) | (0<<CS01) | (1<<CS00); // Prescaler auf 1024
       OCR0A = 156;                                 // um ca. 10ms zu erreichen
       TIMSK0 |= (1<<OCIE0A);                        // Interrupt "TIMER0_COMPA_vect" aktivieren
    }
    Es muss an diesem Code liegen.
    Vermutlich passt das nicht zusammen. Ich weiß leider nicht was OCIE0A ist, oder was der Unterschied zwischen Match A und Match B ist.
    Ist OCIE0A =Match A und OCIE0B = Match B ?

    Ein Buch mit sieben Siegeln. Habe auch noch keine Lektüre gefunden wo das verständlich erklärt ist.

    Wäre nett wenn mir jemand sagt, wo der Fehler in dem Code oben ist.

    Ich möchte das der Timer etwa alle 10ms auslöst und in der ISR Routine einen Zähler hochzählt.

    Dazu muss ich wissen wo oben der Fehler liegt und ob das überhaupt mit Compare Match A geht.

    Gruß, Andreas




    *********EDIT**************

    Ich habe nochmal nachgesehen, das mit dem CTC scheint so falsch nicht zu sein, denn ich will ja das er nur bis 156 geht und nicht die Hardware-grenze nimmt.
    nd der Vergleich mit dem Wert aus OCR0A ist dann diese Compare Match A Geschichte.
    Warum das bei mir nicht geht weiß ich allerdings nicht.
    Habe nen 16 Mhz Quarz. Diese Info fehlte noch um den Wert für den Prescaler nachzuvollziehen.

    Habe den Code aus der ISR übrigens mal in die Main gepackt. Er funktioniert einwandfrei. Es muss also daran liegen das die ISR nicht ausgelöst wird.

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Karlsruhe
    Alter
    36
    Beiträge
    1.225
    Es fehlen einige wichtige Informationen:
    Welcher AVR?
    Interrupts global aktiviert? ( sei(); )
    ISR angelegt?

    Außerdem kannst du beide Zugriffe auf TCCR0A zusammenfassen, das spart Flash weil GCC sonst erst den ersten Zugriff durchführt, dann das ganze wieder einliest, die zweite Modifikation anwendet und dann alles zurückschreiben muss.

    mfG
    Markus

  3. #3

    Re: Problem mit Timer

    Zitat Zitat von MechMac
    Es muss an diesem Code liegen.
    Aha. Warum so sicher?
    Habe den Code aus der ISR übrigens mal in die Main gepackt. Er funktioniert einwandfrei. Es muss also daran liegen das die ISR nicht ausgelöst wird.
    Und was hält dich davon ab, einfach mal den ganzen Code hier zu posten? Du würdest doch auch nicht auf die Idee kommen, mit dem linken Vorderreifen in der Hand zur KFZ Werkstatt deines Vertrauens zu gehen und zu sagen "Der Wagen springt nicht zuverlässig an, bitte schaut mal nach was da los ist". Also poste doch einfach ein vollständiges Programm, inkl header, main() etc., dann kann man dir ohne unzählige Rückfragen helfen.

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    08.03.2010
    Beiträge
    66
    Folgenden Code habe ich zum testen des Timers verwendet:

    Code:
    #include <avr/io.h>
    #ifndef F_CPU
    /* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert 
       (z.B. durch Übergabe als Parameter zum Compiler innerhalb 
       des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
       "nachträgliche" Definition hinweist */
    #warning "F_CPU war noch nicht definiert, wird nun mit 16000000 definiert"
    #define F_CPU 16000000UL     /* Quarz mit 16.0000 Mhz */
    #endif
    #include <util/delay.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include <inttypes.h>
    
    int duration;
    
    
    //******
    //ISR
    //******
    ISR (TIMER0_COMPA_vect)
    {
    duration++;
    switch (duration)
    	{
    	case 100:  PORTD  |=  (1 << DDD6 ); break;
        case 200: PORTD  &= ~(1 << DDD6 ); duration=0; break;  
        default: break;
        } 
    
    } 
    
    
    
    //******
    //INIT
    //******
    void Timer0_init(void)
    {
    TCCR0A =  (1<<WGM01);                        // Timer im CTC-Modus
    TCCR0A |= (1<<CS02) | (0<<CS01) | (1<<CS00); // Prescaler auf 1024
    OCR0A = 156;                                 // um ca. 10ms zu erreichen
    TIMSK0 |= (1<<OCIE0A);                       // Interrupt "TIMER0_COMPA_vect" aktivieren
    }
    
    
    
    //******
    //MAIN
    //******
    int main(void)
    {
    DDRD =  (1 << DDD6) ;
    Timer0_init(); 
    sei();
    while(1)
    	{
    
    	}
    }

    Wie gesagt, wenn ich den Code aus der ISR zusammen mit nem 10ms delay in die Main kopiere, geht es.

    Gruß, Andreas



    ******EDIT******
    Ups, hatte ich vergessen. Es ist ein ATmega644



    *****EDIT 2*****
    Habe den Fehler gefunden.
    Es lag tatsächlich am INIT.

    Ich habe geschrieben:
    Code:
    TCCR0A =  (1<<WGM01);                        // Timer im CTC-Modus
    TCCR0A |= (1<<CS02) | (0<<CS01) | (1<<CS00); // Prescaler auf 1024
    Es muss aber heißen:
    Code:
    TCCR0A =  (1<<WGM01);                        // Timer im CTC-Modus
    TCCR0B |= (1<<CS02) | (0<<CS01) | (1<<CS00); // Prescaler auf 1024
    Nun funktioniert es.

  5. #5
    Code:
    volatile int duration;
    Ohne den Rest wirklich nachvollzogen zu haben, solltest du das dringend probieren

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    08.03.2010
    Beiträge
    66
    Ich meine gelesen zu haben dass das "volatile" nur dann erforderlich ist, wenn auch von außerhalb der ISR auf die Variable zugegriffen werden soll.

  7. #7
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Es sollte auch ohne Volatile gehen. Die Variable ist aber nicht initialisiert.

    Die initialisierung vom Timer sollte man mit einem = statt einem |= machen. Dann hat man alle Bits definiert, und muß nicht ggf. noch suchen wo die anderen Festgelegt sind.

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress