www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega644 16bit Timer Compare Interrupt


Autor: Nick Olaus (lpt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen ich brauche mal etwas Hilfe.

Ich will einen Timer Programmieren der von 50ms bis zu 10min einstellbar 
sein soll.

Das Problem ist das mein Interrupt sich in der Simulation aufhängt.
Er durchläuft ein paar mal hintereinander die ISR und startet dann das 
gesamte Programm  neu. Das soll heißen er beendet eine Endlosschleife 
und beginnt mit der Initaliesierung des Programms. Seinen Compare Wert 
erreicht er in der Simulation aber nie.

In Echt macht sich der Fehler etwas anders bemerkbar.
Der Controller wird beim erreichen des Eingestellten Timerwert 
zurücksetzt (Reset). Das soll er aber eigentlich nicht.

Das Beispielprogramm womit ich im Augenblick experimentiere soll 
eigentlich nur 1x Blinken wenn Aufnahme gesetzt ist.
//****************************************************************************************************
//*****                                               *****
//*****                    Interrupt                       *****
//*****                                               *****
//****************************************************************************************************
//                 ***Wenn Timer Interrupt auslöst dann ausführen***
//                 -------------------------------------------------
  ISR (TIMER1_COMPA__vect)                // Interrupt Vektorvariable vom Timer1 Compare
    {
      Time = Time + 1;              // Time um 1 erhöhen

      if (Time == Durchlauf)            // Time = die Anzahl wie oft der Interrupt 
        {                    // Durchlaufen werden soll
/*
      Aufnahme = 0;
      Zustand = 0x07;      // Zustand = Aufnahme
      PortD_OUT();      // LED setzen
      _delay_ms(1000);      // Warten damit LED Zeit hat zum aufleuchten
      Zustand = 0x00;      // Zustand = Aufnahme
      PortD_OUT();      // LED setzen
*/

          Aufnahme = 1;            // Merker für Aufnahmen setzen
      //    Time    = 0;            // Time zurücksetzen
        }
    }

//****************************************************************************************************
//*****                                               *****
//*****                    Hauptprogramm                     *****
//*****                                               *****
//****************************************************************************************************
int main (void) 
  {
    DDRA = 0xBA;                  // PortA PIN 0, 2, 6 als Eingang
                            // PortA alle anderen Pins als Ausgang 
    
    DDRB = 0xFF;                  // PortB alle Pins als Ausgang

    DDRC = 0xFF;                  // PortC alle Pins als Ausgang

//----------------------------------------------------------------------------------------------------
//                 ***Init Funktionen***
//                ---------------------
    vdip1_init();                    // VNC1L Initialisierung
    AD_Wandler_init();                // AD-Wandler Initialisierung
//    Timer_init;                    // Timer Interrupt wird später Initialisiert

....
...
..
.


//                 ***init Interrupt für Timer***
//                 ------------------------------  
  cli();                        //alle Interrupts sperren um 16Bit Register zu beschreiben
  
  TCCR1A = 0x00;                    //keine PWM und keine Interrupt Ausgabe
  TCCR1B = Vorteiler;                  //Compare Modus & Vorteile setzen
//                Vergleichs- Regiser setzen
  OCR1AH = Byte1;                    // 16 Bit Compare Register A obere  8 Bits 
  OCR1AL = Byte0;                    // 16 Bit Compare Register A untere 8 Bits
  
  sei();                        // alle Interrups wieder freigeben 

  TIMSK1 |= (1<< OCIE1A);               // Compare Interrupt aktivieren//*/

// ****************************************************************************************************
// *****            Hauptschleife zum messen der Signale                   *****
// ****************************************************************************************************



while (1)
{
  if (Aufnahme == 1)                  // Wenn Datenlogger aufnehmen soll
    {
      cli();                        //alle Interrupts sperren um 16Bit Register zu beschreiben

      Aufnahme = 0;

    //  Zustand = 0x07;      // Zustand = Aufnahme
      PORTD = 0xFF;
    //  PortD_OUT();      // LED setzen
      _delay_ms(300);      // Warten damit LED Zeit hat zum aufleuchten

    //  Zustand = 0x00;      // Zustand = Aufnahme
      PORTD = 0x00;
    //  PortD_OUT();      // LED setzen
  
      sei();                        // alle Interrups wieder freigeben 
    }
}
//                ***Aktiv ENDE***
//====================================================================================================
//    abfahren ();                    // Stop Taster auswerten

  return 0;
  }


Das merkwürdige ist das es genau so vor ein paar Tagen noch funktioniert 
hat.
Ich hab bloß noch mal denn Controller wechseln müssen und etwas an ein 
paar Funktonen geändert und jetzt klappt es nicht mehr.

Ich benutze einen ATmega644 mit 12Mhz.

Es wäre echt nett wenn mir jemand helfen kann.

mfg
LPT

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Codefetzen ist nicht vollständig. Es fehlt als wichtige Information, 
wie die Variable Aufnahme definiert ist. Stichwort volatile und 
atomar

Die cli/sei Klammer in main() um das _delay_ms(300) würde ich kritisch 
hinterfragen. Einen Timer will man normalerweise durchlaufen lassen und 
nicht 300ms lang ausbremsen.

Die 1s Pause in der ISR ist derzeit zwar auskommentiert, lässt aber 
übles ahnen für den Nicht-Testcode. Mit Interrupts/Timern programmiert 
man anders: nebenläufig statt aufeinanderfolgend. Wenn du meinst in der 
ISR einen Delay zu brauchen, ist was faul und die Programmlogik muss 
überarbeitet werden.

Es würde IMHO helfen, wenn du besser in eigenen Worten beschreibst, was 
du machen willst, bevor du ausformulierten Code schreibst.

Autor: Nick Olaus (lpt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry war gestern Abend etwas spät als ich das geschrieben habe.

Mein Programm soll ohne Interrupfunterbrechung 17 Werte aufnehmen.

Danach wird der Timerinterrupt aktiviert. Der Interrupt aktiviert den 
nächsten Aufnahmezyklus. In der Pausen Zeit wird der USB-Stick mit denn 
Messdaten beschrieben

Dass das dem Interrupt Betreib etwas wiederspricht ist mir auch klar.

Was das auskommentiert in der ISR angeht, dass gehört dort eigentlich 
nicht hin.
Und war nur dafür da, um zu sehen ob der Interrupt überhaupt 
abgearbeitet wird. Sprich bei Interrupt LED aufblinken lassen. Das hätte 
ich wieder löschen sollen bevor ich es Online setze.

Die Variable Aufnahme ist Global angelegt und zumindest in der 
Simulation funktioniert es.

Allerdings ist mir nicht ganz klar ob der Abschnitt
"***init Interrupt für Timer***"

vor der main stehen muss oder ob ich sie auch als Funktion aufrufen 
kann.

Weil in main wollte ich eigentlich erst festlegen welche Einstellung ich 
vornehmen will.

  switch (Timerwert)
    {
  // Zeiteinstellung = 1  Pausen-Zeit = 10ms
      case 1:  Durchlauf = 1;            // 1 x 10ms
          Vorteiler = 0x0A;          // Vorteiler = 8
          Byte1     = 0x00;  //0x07;          // Vergleichswert = 1901
          Byte0     = 0x9F;  //0x6D;
          break;
...
..
.
      // Zeiteinstellung = 8  Pausen-Zeit = 10min
      case 8:  Durchlauf = 120;          // 120 x 5s          
          Vorteiler = 0x0D;          // Vorteiler = 1024
          Byte1     = 0x1C;          // Vergleichswert = 7327
          Byte0     = 0x9F;
          break;

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ALso:
Mit den Code Fetzen kann man immer noch nichts anfangen.
Bei solchen Problem ist es nicht ungewöhnlich, dass das eigentliche 
Problem genau in den Teilen sitzt, die du nicht zeigst.

Ein 'Selbst-Reset' kann zb auf einen zwar freigegebenen Interrupt 
hindeuten, für den es aber keine ISR gibt.
Nur: Wie soll das jemand überprüfen, wenn du nicht den ganzen Code 
zeigst?

Autor: Nick Olaus (lpt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ganze Programm sind etwa 1500 Zeilen und das meiste ist dafür 
verantwortlich denn USB-Stick zu beschreiben.

Aber ich stelle mal denn ganzen Code von der Interrupt Test Datei 
online.
Da ist der Original Text stark reduziert und trotzdem sind noch eine 
Menge Variabelenleichen drin. Aber das Programm ist einfach zu groß um 
das jemandem zuzumuten.

Aber vielleicht kann ja jemand damit etwas anfangen.

//****************************************************************************************************
// Initialiesierung
#define F_CPU 1000000UL                  // Taktrate (12MHz) festlegen
#include <avr/io.h>                       // Datei für Ein und Ausgänge  
#include <stdlib.h>                    // Standart LIB
#include <util/delay.h>                      // Ersetzt durch delay.c
//#include <stdint.h>                      // Für ADWandler aber damals schon auskommentiert
#include <string.h>                       // Stingfunktionen
#include <stdio.h>                        // Standardfunktionen
#include <avr/interrupt.h>                // Datei für Interrupt

//#include "delay.c"                         // Pausen-Funktionen

//****************************************************************************************************
// Definebereich der Ein- und Ausgabe Port's

//                 ***Definebereich der Multipleyer Freigaben***
//                 ---------------------------------------------
#define MUX_Digi_U    PORTC = 0x00                // MUX auf Digi Spannungsaufnahme setzen
#define MUX_Schalter1  PORTC = (1<<PIN6)              // MUX auf "Schalter1 abfrage"  setzen
#define MUX_LED      PORTC = (1<<PIN6) | (1<<PIN5)        // MUX auf "LED setzen" setzen
#define MUX_Schalter2  PORTC = (1<<PIN6) | (1<<PIN5) | (1<<PIN4)  // MUX auf "Schalter2 abfragen" setzen


//----------------------------------------------------------------------------------------------------
//                 ***Definebereich I/O PORT für VDIP1 Komunikation***
//                ---------------------------------------------------
#define S_RE_VNC  PORTA |=  (1<<PIN3)                // VDIP1 Reset setzen
#define R_RE_VNC  PORTA &= ~(1<<PIN3)                // VDIP1 Reset zurücksetzen

#define S_SCLK     PORTA |=  (1<<PIN4)                // VDIP1 Clock Setzen
#define R_SCLK    PORTA &= ~(1<<PIN4)                // VDIP1 Clock Rücksetzen

#define S_SDI    PORTA |=  (1<<PIN5)                // VDIP1 Seriel-Daten-In Setzen
#define R_SDI    PORTA &= ~(1<<PIN5)                // VDIP1 Seriel-Daten-In Rücksetzen

// SDO_VNC      PORTA     (    PIN6)                // VDIP1 Seriel-Daten-Out
                                  // wird in der Funktion 
                                  // SDO_VNC(void) realiesiert

#define S_CS_VNC  PORTA |=  (1<<PIN7)                // VDIP1 Freigeben
#define R_CS_VNC  PORTA &= ~(1<<PIN7)                // VDIP1 Sperren

//****************************************************************************************************
//*****                                               *****
//*****                  Variablenbereich                     *****
//*****                                               *****
//****************************************************************************************************
//                ***Variablen für main***
//                ------------------------
char Aufnahme = 0;                    // Merker für die Aufnahme (wird vom Timer gesetzt)
char Aktiv    = 0;                    // Merker für Aktiv 
          //char Ende    = 0;          // Merker für das Abfahren des Gerätes
char Stoerung = 0;
char x=1;  //***Wieder löschen
//             ***Adressierung für Unterfunktion PortD_IN***
//            ---------------------------------------------
char Digi_U     = 0;                    // Adressenzuweisung für die Funktion PortD_IN
char Schalter1 = 1;                    // Adressenzuweisung für die Funktion PortD_IN
char Schalter2 = 2;                    // Adressenzuweisung für die Funktion PortD_IN

//----------------------------------------------------------------------------------------------------
//                 ***Variablen für Schalter***
//                ----------------------------
unsigned char n_Stromwerte;                // Anzahl der zu messenden Ströme
unsigned char Strom_Kanal;                // Zur Zeit gemessener Stormkanal
unsigned char n_Spannungswerte;              // Anzahl der zu messenden Spannungen
unsigned char Spannungs_Kanal;              // Zur Zeit gemessener Spannungskanal
unsigned char Zustand;                  // zur ansteuerung der LED's
unsigned char Timerwert;                // für Timereinstellung
unsigned char Wert = 0;                  // Einlesewert

//----------------------------------------------------------------------------------------------------
//                ***Variablen für Timer***
//                -------------------------
unsigned char Timerwert;                // Abtastzeit
unsigned char Timer  = 0;                // Variablen für Timer
unsigned int  Durchlauf;                // Variablen für Timer Wie Timer durchlaufzähler
unsigned int  Time;                    // Zähler für die Anzahl der Timerdurchläufe
unsigned char Vorteiler;                 // Vorteiler für Interrupt
unsigned char Byte1;                   // Vergleichswert für Timerinterrupt (höhes Byte)
unsigned char Byte0;                  // Vergleichswert für Timerinterrupt (nidriges Byte)

//----------------------------------------------------------------------------------------------------
//                ***Variablen für VDIP1***
//                -------------------------
char Daten_Typ0 = 0;                  // Daten  Byte lesen
char Daten_Typ1 = 1;                  // System Byte lesen

char NEU    = 0;                  // Neue Text Datei erzeugen
char ALT    = 1;                  // Alte Text Datei erweitern

char vdip1_fehl     = 1;                  // Variable für Prüfanweisung Fehler Chack
char vdip1_ok     = 2;                  // Variable für Prüfanweisung OK   Chack
char vdip1_Echo    = 3;                  // Variable für Prüfanweisung Echo   Chack
char vdip1_Promt   = 4;      //????          // Variable für Prüfanweisung Promtzeichen Chack
//                ***Wiederhohlversuche***
unsigned int durchlaufrate = 50;            // max Anzahl der Zugriffversuche auf das VDIP1
unsigned int R_W_Versuche  =500;            // max Anzahl der R/W Versuche von einem Byte
unsigned int Kommversuche  =  5;            // max Anzahl an Kommunikationsversuchen je Zeichen
unsigned int Sendeversuche = 30;            // max Anzahl der Echo Versuche
                            // bzw der Versuch Datei anlegen oder zu erweitern
//----------------------------------------------------------------------------------------------------
//               ***Variablen für AD_Wandlung***
//              -------------------------------
unsigned int n = 0;                    // n ist für die Ablage in Messwerte notwendig
char Adresse;                      // Adresse für Strom- oder Spannungs- Kanal
char Geschwindigkeit = 0x87;              // Wandlergeschwindigkeit
//----------------------------------------------------------------------------------------------------
//                 ***Datenfelder***
//                -----------------
char *Dateiname[] = {"Datalog.txt"};          // Datei Name in der die Daten gespeichert werden
char Einstellungen[3];                  // Einstellwerte des Datenloggers

volatile char lese_buffer[15];                 // Empfangsbuffer   (15Byte groß) Globalveränderbar
unsigned char sende_buffer[20];                 // Sendebuffer     (20Byte groß) Globalveränderbar

unsigned char Messfeld[800];              // Feld für maximale Aufzeichnungsgeschwindigkeit
                            // (800 Messwerte aufnehmen und dann an USB senden)

unsigned char Messwert[17];                // ein Feld für 8 Anal Stromwerte    8 x 1Byte
                            //        8 Anal Spannungswerte  8 x 1Byte
                            //        8 Digi Spannungswerte   1 x 1Byte 
                            //                    ---------
                            //                    17x 1Byte

//****************************************************************************************************
//*****                                               *****
//*****                    Funktionen deklarieren                 *****
//*****                                               *****
//****************************************************************************************************

//                 ***Funktionen zur PORT Ein und Ausgabe***
//                 -----------------------------------------
char SDO_VNC(void);                    // init SDO VDIP-Out(Daten vom µC zurücklesen)
void PortD_OUT(void);                  // Daten am PortD ausgeben
unsigned char PortD_IN(char);              // Daten am PortD einlesen


//                 ***Funktionen für Datenspeichern***
//                 -----------------------------------
char USB_Datei_anlegen (void);               // Verbindung zum Sick prüfen und Datei anlegen 
char USB_Datei_erweitern (char*, unsigned int);      // USB Datei erweitern 

//                 ***Funktionen für VDIP1***
//                 --------------------------
//char SDO_VNC(void);    // siehe PORT Ein/Ausgabe  // init SDO (Dateneingang vom µC) 
void vdip1_init(void);                  // init VDIP1
char vdip1_Echocheck (void);              // VDIP1 auf Echo Prüfen

char SPI_byte_lesen(char);                // Byte über SPI einlesen
char vdip1_byte_lesen(void);               // Byte von dem VDIP1 lesen und Status auswerten
char vdip1_string_lesen(char *);
char vdip1_pruefen(char);                // String aus dem VDIP1 lesen und auswerten

char SPI_byte_schreiben(char);              // Byte über SPI schreiben
char vdip1_byte_schreiben(char);             // Byte in das VDIP1 schreiben
char vdip1_befehl_schreiben(unsigned char*);      // String in das VDIP1 schreiben
char vdip1_txtfile_schreiben(char *, char *, char, unsigned int);// Text   Dabei-Daten auf USB schreiben
char vdip1_bin_file_scheiben(char *, char *, unsigned int);     // Binäre Datei-Daten auf USB schreiben

//                 ***Funktionen für AD-Wandlung***
//                 --------------------------------
void AD_Wandler_init(void);                // init AD-Wandler
unsigned char AD_Wandler (void);              // AD-Wandlerfunktion für PortA Kanal 0

//                 ***Funktionen für Störungsauswertung***
//                 ---------------------------------------
void stoerung (char);                  // Störung setzen und auf Quit warten
void abfahren (void);                  // Messgerät abfahren

void init_Timer (void);
//****************************************************************************************************
//*****                                               *****
//*****                    Interrupt                       *****
//*****                                               *****
//****************************************************************************************************
//                 ***Wenn Timer Interrupt auslöst dann ausführen***
//                 -------------------------------------------------
  ISR (TIMER1_COMPA__vect)                // Interrupt Vektorvariable vom Timer1 Compare
    {
      Time = Time + 1;              // Time um 1 erhöhen

      if (Time == Durchlauf)            // Time = die Anzahl wie oft der Interrupt 
        {                    // Durchlaufen werden soll
          Aufnahme = 1;            // Merker für Aufnahmen setzen
          Time    = 0;            // Time zurücksetzen
        }
    }



//****************************************************************************************************
//*****                                               *****
//*****                    Hauptprogramm                     *****
//*****                                               *****
//****************************************************************************************************
int main (void) 
  {
    DDRA = 0xBA;                  // PortA PIN 0, 2, 6 als Eingang
                            // PortA alle anderen Pins als Ausgang 
    
    DDRB = 0xFF;                  // PortB alle Pins als Ausgang

    DDRC = 0xFF;                  // PortC alle Pins als Ausgang

//----------------------------------------------------------------------------------------------------
//                 ***Init Funktionen***
//                ---------------------
    vdip1_init();                    // VNC1L Initialisierung
    AD_Wandler_init();                // AD-Wandler Initialisierung
//    Timer_init;                    // Timer Interrupt wird später Initialisiert

//----------------------------------------------------------------------------------------------------
//                ***Starttaster abfragen***
//                --------------------------
/*
  while (Aktiv == 0)                  // Auf Starttaster warten
    {
      if (vdip1_Echocheck ())            // VDIP1 USB Stick überprüfen
        {
          Stoerung = 1;            // Wenn Störung: Störung setzen und
        }
  
      if ( Stoerung == 1)
        {
          stoerung (Stoerung);        // Störung auswerten        
        }
        else
          {
            abfahren ();          // Stop Taster auswerten
            Zustand = 0x01;          // Zustand = Bereit
            PortD_OUT();          // LED setzen
            _delay_ms(1000);          // Warten damit LED Zeit hat zum aufleuchten

            Aktiv = PortD_IN (Schalter2);  // PortD (Taster Start) einlesen und
            Aktiv = Aktiv & 0x10;       // Maskieren

            if (Aktiv)            // Wenn Starttaster gedrückt dann
              {
                Aktiv = 1;        // Aktiv = 1
                Aufnahme = 1;      // Es bebinnt sofort ein Aufnahmezyklus
                            // Der Interrupttimer startet dann die nächsten
                Zustand = 0x02;      // Zustand = Aufnahme
                PortD_OUT();      // LED setzen
              }
          }
    }
//*/  
//----------------------------------------------------------------------------------------------------
//                 ***Die Stromeinstellung einlesen***
//                -----------------------------------
     Wert        = PortD_IN (Schalter2);      // PortD (Stromkanaleinstellung) einlesen
  n_Stromwerte    = Wert & 0x0F;            // Wert Maskieren und in "n_Stromwerte" ablegen
  
  if (n_Stromwerte == 9)                // Wenn die 9 Eingestellt ist
    {
      n_Stromwerte = 8;              // wird eine 8 geschrieben da 9 nicht vergeben
    }
//                 ***Die Spannungseinstellung einlesen***
//                ---------------------------------------
  Wert       = PortD_IN (Schalter1);      // Schalter für Spannungskanälen abfragen
  n_Spannungswerte = Wert & 0x0F;            // Wert Maskieren und in "n_Spannungswerte" ablegen
  
  if (n_Spannungswerte == 9)              // Wenn die 9 Eingestellt ist
    {
      n_Spannungswerte = 8;            // wird eine 8 geschrieben da 9 nicht vergeben
    }
//                 ***Die Timereinstellung einlesen***
//                -----------------------------------
  Wert       = PortD_IN (Schalter1);      // Schalter für Timereinstellung abfragen
  Wert       = Wert & 0xF0;            // Wert Maskieren
  Timerwert     = Wert >> 4;            // Wert um 4Bit Schiften und in "Timerwert" ablegen

//----------------------------------------------------------------------------------------------------
/*
//       ***Datei auf USB-Stick anlegen und die Einstellwerte des Datenloggers ablegen***
//      --------------------------------------------------------------------------------

//                ***Basisdaten erstellen***
//                --------------------------
  Einstellungen[0] =   n_Stromwerte;          // Anzahl der Stromwerte 
  Einstellungen[1] =   n_Spannungswerte;        // Anzahl der Spannungswerte
  Einstellungen[2] =   Timerwert;            // Timereinstellung

//                ***USB Datei anlegen***
//                -----------------------
  if (USB_Datei_anlegen ())              // USB Datei anlegen und Basisdaten schreiben
    {
      Stoerung = 1;                // bei Fehler setze Stoerung
    }

  if ( Stoerung == 1)
    {
      stoerung (Stoerung);            // Störung auswerten        
    }
//*/
//----------------------------------------------------------------------------------------------------

//                ***Timereinstellung vornehmen***
//                --------------------------------
  switch (Timerwert)
    {  //Zeiteinstellung = 0  Pausen-Zeit = 0
      case 0:  Durchlauf = 0xFF;          // immer Messung starten
          break;

      // Zeiteinstellung = 1  Pausen-Zeit = 10ms
      case 1:  Durchlauf = 1;            // 1 x 10ms
          Vorteiler = 0x0A;          // Vorteiler = 8
          Byte1     = 0x00;  //0x07;          // Vergleichswert = 1901
          Byte0     = 0x9F;  //0x6D;
          break;

      // Zeiteinstellung = 2  Pausen-Zeit = 50ms        
      case 2:  Durchlauf = 1;            // 1 x 50ms
          Vorteiler = 0x0A;          // Vorteiler 8
          Byte1     = 0x25;          // Vergleichswert 9505
          Byte0     = 0x21;
          break;

      // Zeiteinstellung = 3  Pausen-Zeit = 100ms  
      case 3:  Durchlauf = 1;            // 1 x 100ms
          Vorteiler = 0x0A;          // Vorteiler 8
          Byte1     = 0x4A;          // Vergleichswert =19010
          Byte0     = 0x42;
          break;

      // Zeiteinstellung = 4  Pausen-Zeit = 1s  


      case 4:  Durchlauf = 1;            // 1 x 1s  
          Vorteiler = 0x0C;          // Vorteiler = 256
          Byte1     = 0x17;          // Vergleichswert = 5909
          Byte0     = 0x15;
          break;

      // Zeiteinstellung = 5  Zeit = 5s  
      case 5:  Durchlauf = 1;            // 1 x 5s
          Vorteiler = 0x0D;          // Vorteiler = 1024
          Byte1     = 0x1C;          // Vergleichswert = 7327
          Byte0     = 0x9F;
          break;

      // Zeiteinstellung = 6  Pausen-Zeit = 30s  
      case 6:  Durchlauf = 6;            // 6 x 5s
          Vorteiler = 0x0D;          // Vorteiler = 1024
          Byte1     = 0x1C;          // Vergleichswert = 7327
          Byte0     = 0x9F;
          break;

      // Zeiteinstellung = 7   Pausen-Zeit = 1min
      case 7:  Durchlauf = 12;            // 12 x 5s
          Vorteiler = 0x0D;          // Vorteiler = 1024
          Byte1     = 0x1C;          // Vergleichswert = 7327
          Byte0     = 0x9F;
          break;

      // Zeiteinstellung = 8  Pausen-Zeit = 10min
      case 8:  Durchlauf = 120;          // 120 x 5s          
          Vorteiler = 0x0D;          // Vorteiler = 1024
          Byte1     = 0x1C;          // Vergleichswert = 7327
          Byte0     = 0x9F;
          break;

      // Zeiteinstellung = 9   Sonderfunktion
      // zur Zeit noch unbenutzt (selbe Einstellung wie case 8:)
      case 9:  Durchlauf = 120;          // 120 x 5s          
          Vorteiler = 0x0D;          // Vorteiler = 1024
          Byte1     = 0x1C;          // Vergleichswert = 7327
          Byte0     = 0x9F;
          break;
    }

//----------------------------------------------------------------------------------------------------



// ****************************************************************************************************
// *****            Hauptschleife zum messen der Signale                   *****
// ****************************************************************************************************

init_Timer ();

while (1)
{
  Aufnahme = Aufnahme;

  if (Aufnahme == 1)                  // Wenn Datenlogger aufnehmen soll
    {
      cli();                        //alle Interrupts sperren um 16Bit Register zu beschreiben

      Aufnahme = 0;

    //  Zustand = 0x07;      // Zustand = Aufnahme
      PORTD = 0xFF;
    //  PortD_OUT();      // LED setzen
      _delay_ms(300);      // Warten damit LED Zeit hat zum aufleuchten

    //  Zustand = 0x00;      // Zustand = Aufnahme
      PORTD = 0x00;
    //  PortD_OUT();      // LED setzen
  
      sei();                        // alle Interrups wieder freigeben 
    }
}
//                ***Aktiv ENDE***
//====================================================================================================
//    abfahren ();                    // Stop Taster auswerten

  return 0;
  }
//****************************************************************************************************
//*****                                               *****
//*****                    Funktionen                       *****
//*****                                               *****
//****************************************************************************************************
//                 ***init Interrupt für Timer***
//                 ------------------------------  
void init_Timer (void)
  {
  cli();                        //alle Interrupts sperren um 16Bit Register zu beschreiben
  
  TCCR1A = 0x00;                    //keine PWM und keine Interrupt Ausgabe
  TCCR1B = Vorteiler;                  //Compare Modus & Vorteile setzen
//                Vergleichs- Regiser setzen
  OCR1AH = Byte1;                    // 16 Bit Compare Register A obere  8 Bits 
  OCR1AL = Byte0;                    // 16 Bit Compare Register A untere 8 Bits
  
  sei();                        // alle Interrups wieder freigeben 

  TIMSK1 |= (1<< OCIE1A);               // Compare Interrupt aktivieren
  
  return;
  }

//****************************************************************************************************
// Daten am PortD ausgeben
//****************************************************************************************************
void PortD_OUT(void)                  // Byte ausgeben
  {
    MUX_LED;                    // Multiplexer auf LED's setzen
    DDRD  = 0xFF;                  // PortD als Ausgang
    PORTD = ~Zustand;                // Daten auf PortD ausgeben

  return;
  }


//****************************************************************************************************
// Daten am PortD einlesen
//****************************************************************************************************
unsigned char PortD_IN(char Adresse)          // Byte lesen
  {
    unsigned char Input;

    DDRD  = 0x00;                  // PortD als Eingang
    PORTD = 0xFF;                  // PortD Pull-Up Widerstände aktivieren
    
    switch (Adresse)
      {
        case 0:  MUX_Digi_U;            // Wenn Adresse 0 Digitale Spannungs einlesen
            break;

        case 1:  MUX_Schalter1;          // Wenn Adresse 1 Schalter1 einlesen
            break;

        case 2:  MUX_Schalter2;          // Wenn Adresse 2 Schalter2 einlesen
            break;
      }
  
    _delay_us(100);                 // 100µs Pause  

    Input = ~PIND;                  // PortD Einlesen und Invertieren da Low aktiv

  
    PortD_OUT();                  // nach dem Einlesen wieder zurückschalten auf 
                            // LED's und auf Ausgabe
  return Input;
  }

Für denn Interrupt unnötige Funktionen (wie zum Beispiel USB Verwaltung, 
an und Abfahren, Messwerterfassung) habe ich mal weg gelassen, damit es 
auch noch etwas überschaubar bleibt. Im Augenblick sollen nur die LEDs 
blinken wenn ich eine Zeit einstelle.

Wie schon geschrieben benutze ich einen ATmega644.
Ich bin für jeden Tipp dankbar.

mfg
LPT

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: swen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ohje...
sag mal was soll das? schon mal aufgefallen, das du beim posten ein 
möglichkeit hast code als datei hochzuladen?

du machst dir damit deinen eigenen thread kaputt. so hilft dir keiner..

ist nur gut gemeint
swen

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So wird das schwierig dir zu helfen.

Was ich tun würde:
Neues Projekt anfangen.
Und dann sukzessive, Schritt für Schritt, ein Subsystem nach dem anderen 
vom alten Projekt in das Neue übernehmen und dort einbauen. Nach jeder 
einzelnen Übernahme ausgiebig testen, ob Anomalien auffallen. Erst dann, 
wenn ich denke, dass der neu hinzugekommene Teil keine Probleme 
verursacht, kommt das nächste Subsystem dazu.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es wird günstig sein, wenn Du den Code reduzierst. Also alles entfernen 
was mit dem fraglichen Timer und seinem Interrupt nichts zu tun hat. 
Kein Code für USB oder AD-Wandlung. Das Ergebnis muss kompilierbar sein.

Damit erfahren wir auch ob das Problem nur mit der Timerprogrammierung 
und Auswertung selbst zu tun hat oder ob auch der Rest bei dem Problem 
eine Rolle spielt.

Autor: Grrrr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Neues Projekt anfangen.

Oder so.

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.