- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 6 von 6

Thema: Interrupt jede Millisekunde

  1. #1
    Erfahrener Benutzer Begeisterter Techniker Avatar von Torrentula
    Registriert seit
    10.10.2009
    Ort
    Procyon A
    Beiträge
    355

    Interrupt jede Millisekunde

    Anzeige

    Powerstation Test
    Hallo RNler!

    Ich habe vor eine Uhr zu bauen mithilfe meines RN-Control (nur testweise). Der Mega644 läuft mit 16MHz und ich verwende Timer0 im CTC modus mit Prescaler 8. Berechnet habe ich den Wert für das Compare-Register OCR0A folgendermaßen:

    ((16000000 / 8 ) / 1000) - 1 = 199

    Ist da etwas falsch? In der ISR lasse ich nur millisekunden, sekunden, minuten und stunden inkrementieren / zurücksetzen. Trotzdem dauert für den Controller 1 Minute nur ungefähr 6 Sekunden^^. Mein Code sieht so aus:

    Code:
    #define F_CPU 16000000UL
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdlib.h>
    #include "standards.h"
    
    volatile unsigned int milliseconds;
    volatile unsigned int seconds;
    volatile unsigned int minutes;
    volatile unsigned int hours;
    
    char buffer[10];
    
    int main(void)
    {
        
        init_USART();
        senchar('v');
    
        TCCR0A = (1<<WGM01); // CTC Mode of Timer 0
        TCCR0B |= (1<<CS01); // Prescaler 8
        
        // ((16000000 / 8) / 1000) = 200
        OCR0A = 200-1; // to get 200 steps 
        
        TIMSK0 |= (1<<OCIE0A); // Enable compare interrupt
        
        // global interrupt enable
        sei();
        
        DDRC |= 0x01;
        PORTC |= 0x01;
        
        while(1)
        {
            itoa(minutes, buffer, 10);
             sendUSART(buffer);
        }
    }
    
    // The compare match handler is called every time
    // TCNT0 = OCR0A = 200 - 1 (200 steps) which gives us
    // exactly 1ms
    ISR (TIMER0_COMPA_vect){
        
        milliseconds++;
        if(milliseconds == 1000){
            
            seconds++;
            milliseconds = 0;
        
            if(seconds == 60){
                minutes++;
                seconds = 0;
            }
            if(minutes == 60){
                hours++;
                minutes = 0;
            }
            if(hours == 24){
                hours = 0;
            }
        }
    }
    MfG

    Torrentula
    Geändert von Torrentula (20.10.2011 um 17:16 Uhr)
    MfG Torrentula

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    11.08.2008
    Ort
    Hallein
    Alter
    32
    Beiträge
    802
    Für solche Sachen solltest du einen speziellen Uhrenquarz verwenden. Der hat ne ganz krumme MHz Zahl, aber mit dieser kann sich dann genau die Zeit berechnen lassen.
    Kultuverein Metal Resurrection, für mehr Bands und Konzerte in Österreich (:

  3. #3
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Die Werte sind nicht initialisiert.

    Zu: OCR0A = 200-1; // to get 200 steps

    Ich glaube, das -1 ist falsch. Bei 200 wird das Zählregister mit 0 beschrieben und dann der Interrupt ausgeführt. Beim Zählen der ms schreibst du ja auch bei 1000 die 0 rein und nicht schon bei 999:

    In CTC mode the counter is cleared to zero when the counter value (TCNT0) matches the OCR0.
    Hier ist atmel scheinbar etwas ungenau, den zu folgender Beschreibung für den "Normal Mode" finde ich keine Entsprechung beim "CTC":
    (In normal operation) the Timer/Counter Overflow Flag (TOV0) will be set in the same timer clock cycle as the TCNT0 becomes zero.

    Was ist daran "krumm"?
    32768 kHz
    http://www.google.de/search?q=frequenz+uhrenquarz

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    probiers mal mit Prescaler 64 und OCR0A=230, damit komme ich ungefähr auf diese Zeit.

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  5. #5
    Erfahrener Benutzer Begeisterter Techniker Avatar von Torrentula
    Registriert seit
    10.10.2009
    Ort
    Procyon A
    Beiträge
    355
    Die Uhr läuft auch mit berichtigtem Wert für OCR0A = 1999 zu schnell und laut allgemeiner Formel für den CTC Modus sollte dieser Wert bei einem Prescaler von 8 und einer Quartzfrequenz von 16MHz eine Interrupt-Frequenz von 1000Hz also jede Millisekunde ergeben.

    MfG

    Torrentula

    EDIT: Damfino bringt die Lösung einfach mal Prescaler 64 probieren... macht für OCR0A dann 249.

    Kann ich die Ausgaben mehrerer itoa() in einen String kombinieren den ich dann an das 7 Segment display sende, so dass mir Stunden + Minuten angezeigt werden? wenn ich die Daten nämlich nicht an einem Stück sende kommt Mist raus.
    Geändert von Torrentula (20.10.2011 um 17:46 Uhr)
    MfG Torrentula

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von radbruch
    Ich glaube, das -1 ist falsch.
    Nein, das ist richtig. Die Beschreibung im Datenblatt ist zwar etwas missverständlich, aber die Formel ein Stück weiter ist dafür absolut eindeutig.


    Zitat Zitat von Torrentula
    Die Uhr läuft auch mit berichtigtem Wert für OCR0A = 1999 zu schnell
    Natürlich. Wie soll denn auch ein 8-Bit-Zähler bis 1999 zählen können?
    MfG
    Stefan

Ähnliche Themen

  1. ATmega644P Millisekunde genau?
    Von HeyHey im Forum AVR Hardwarethemen
    Antworten: 7
    Letzter Beitrag: 18.03.2011, 19:10
  2. Timer/Interrupt Problem. LED soll jede Minute blinken
    Von dg im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 18.05.2007, 20:04
  3. Jede Sekunde ein Timer Interrupt
    Von Johannes G. im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 06.10.2006, 16:52
  4. Gibt es empfängermodule für jede Wellenlänge?
    Von Katja im Forum Sensoren / Sensorik
    Antworten: 3
    Letzter Beitrag: 03.06.2006, 22:58

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad