- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 5 von 5

Thema: Probleme mit Timer und ATMega 32

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    03.10.2007
    Beiträge
    15

    Probleme mit Timer und ATMega 32

    Anzeige

    Praxistest und DIY Projekte
    Hallo Leute !
    Habe ein kleines Uhrenprogramm. Wenn der Timer1 des Atmega32 einen Overflow hat soll eine Sekunde dazugezählt werden. Leider arbeitet der ATMega aber nicht das Interruptprogramm ab. Was mache ich falsch ??
    (Programm siehe unten ) In meiner Main wird Start_Clock() aufgerufen. Timer läuft auch .. nur die ISR wird nicht abgearbeitet.


    Gruß Steffen


    #include "clock.h"

    //Die Uhrzeit steht in folgenden Variablen
    unsigned char ss=0; //Globale Variable für die Sekunden
    unsigned char mm=12; //Globale Variable für die Minuten
    unsigned char hh=12; //Globale Variable für die Stunden
    unsigned char day=12; //Globale Variable für den Tag
    unsigned char mon=12; //Globale Variable für den Monat
    unsigned int year=2007; //Globale Variable für das Jahr


    //################################################## ##########################
    //Overflow Interrupt wird bei 59 Sekunden ausgelöst
    ISR(TIMER1_OVF_vect)
    //################################################## ##########################
    {

    //Zurücksetzen des Timers
    TCNT1 = 65535 - (SYSCLK / 1024);
    //1 Sekunde addieren
    Add_one_Second ();

    }


    //################################################## ##########################
    //Addiert 1 Sekunde
    void Add_one_Second (void)
    //################################################## ##########################
    {
    ss++;//Addiere +1 zu Sekunden
    if (ss == 60)
    {
    ss = 0;
    mm++;//Addiere +1 zu Minuten
    if (mm == 60)
    {
    mm = 0;
    hh++;//Addiere +1 zu Stunden
    if (hh == 24)
    {
    hh = 0;
    if (hh== 0)
    {
    day++;//Addiere +1 zu Tag

    }
    }
    }
    }

    }

    //################################################## ##########################
    //Diese Routine startet und initialisiert den Timer
    void Start_Clock (void)
    //################################################## ##########################
    {

    //Timer 1 Overflow einschalten
    TIMSK |= (1 << TOIE1);
    //Prescaler auf 1024 setzen
    TCCR1B |= (1<<CS10 | 0<<CS11 | 1<<CS12);
    //Timer 1 auf 0 setzen
    TCNT1 = 65535 - (SYSCLK / 1024);
    }

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    31.08.2005
    Ort
    bei Graz
    Alter
    34
    Beiträge
    225
    Hallo,
    schau mal ob die Interruptroutine (nur) ein mal aufgerufen wird. Das war bei mir nämlich eben erst der Fall. Habs inzwischen behoben, aber warum das jetzt funktioniert weiß ich leider noch nicht.

    Mit meiner Lösung würde das so aussehen:
    Code:
    ISR(TIMER1_OVF_vect)
    {
      cli();                                                //Global Interrupt Flag löschen
      TCNT1 = 65535 - (SYSCLK / 1024);   //Zurücksetzen des Timers
      Add_one_Second ();                         //1 Sekunde addieren
      sei();                                              //Global Interupt Flag wieder setzten
    }
    Vielleicht funktionierts

    lg MoFe

    ps: Bitte [ code] Source Code [ /code] verwenden, mach das ganze übersichtlicher.

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Und auch den gesamten Code zeigen, denn warum bist du dir sicher das der Fehler gerade in dem Bereich liegt. Man sieht z.B. nicht ob du sei(); gesetzt hast.
    Es wäre ausserdem Übersichtlicher und vom Code her kürzer, wenn du den OutputComparematch Interrupt benutzen würdest.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    03.10.2007
    Beiträge
    15
    Hallo noch mal ...
    Danke für die schnellen Antworten. Habe die Lösung von Moritz probiert. Funzt leider immer noch nicht.
    Hier ist noch der restliche Quellcode (Danke Hubert)

    //Hauptprogramm
    int main (void)
    //################################################## ##########################
    {
    //Globale Interrupts einschalten
    sei();


    //Starten der DCF77 Uhr
    Start_Clock();

    usart_write ("\nDCF 77 Ho Ho Ho Jo\n\n");
    //Ausgabe der Zeit auf der Seriellen Schnittstelle in einer Endlosschleife
    while (1)
    {

    if (TCNT1==65535)
    {
    TCNT1 = 65535 - (SYSCLK / 1024);
    Add_one_Second();

    }


    }

    return (1);
    }


    Wenn ich die roten Zeilen statt der ISR einbaue funktioniert alles (sind die gleichen Zeilen wie in der ISR). Warum funzt dann die ISR nicht ?

    Gruß Steffen

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    55
    Beiträge
    524
    Hallo,

    Zitat Zitat von Moritz f.
    ps: Bitte [ code] Source Code [ /code] verwenden, mach das ganze übersichtlicher.
    Ist das so schwer?

    Wird die ISR wirklich nicht aufgerufen oder nur der Code nicht so ausgeführt wie du möchtest?
    Deklariere mal alle Variablen ,die innerhalb der ISR also auch innerhalb von 'Add_one_Second' genutzt werden, als volatile.

    BTW. SYSCLK wird ja sicher im Header definiert sein. 65535-(SYSCLK/1024) ist damit auch konstant. Würde ich auch im Header definieren.

    Gruß

    Jens

Berechtigungen

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

LiFePO4 Speicher Test