Forum: Mikrocontroller und Digitale Elektronik ISR funktioniert nicht


von Matze (Gast)


Lesenswert?

Hey,
Bin neu im Form habe aber schon etwas Erfahrung mit der Programmierung 
in C.
Wollte euch bitten mal meinen Code anzuschauen und mir sagen warum die 
ISR nicht ausgeführt wird.
Vielen Dank für eure Hilfe

MfG.

#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include "ports_init_4bit.h"


volatile unsigned int millisekunde  =0;
volatile unsigned int sekunde    =0;
volatile unsigned int minute    =0;
volatile unsigned int stunde    =0;


int main(void)
{

INITIALISIERUNG_SYSTEMPORTS();          //Ports initialisieren

  TCCR2=0b00001100;
  OCR2=250-1;
  sei();               //Global Interrupt Flag freischalten
  TIMSK=(1<<OCIE2);    //Timer/Counter 2 Interrupt Register 
freigeschalten


  while(1)
  {
    if (sekunde==2)
    {
    PORTD|=(1<<PD7);
      if (sekunde==4)
      {
      PORTD&=~(1<<PD7);
      }
    }
  }
}





ISR (TIMER2_COMP_vect)
    {
    millisekunde++;
      if (millisekunde==1000)
      {
      millisekunde=0;
      sekunde++;
      }
        if (sekunde==60)
        {
        sekunde=0;
        minute++;
        }
          if (minute==60)
          {
          minute=0;
          stunde++;
          }
    }

von Karl H. (kbuchegg)


Lesenswert?

TCCR2=0b00001100;


Ist da bei irgendeinem dieser Bits ein CS Bit dabei?


Biiiiiiitteeee
Schreib das nicht in Binärschreibweise. Da sieht man genau gar nichts, 
wenn man nicht zufällig die Bitbelegung der Konfigurationsregister 
komplett auswendig weiss.

Schreibs doch so

   TCCR2 = ( 1 << CS20 ) | ( 1 << CS21 );

oder welches Bit du dann eben brauchst.
Dann sieht man zumindest, dass du ein oder mehrere CS Bits setzt und 
weiß: Jup, da ist zumindest ein Vorteiler beteiligt. Der kann jetzt 
immer noch falsch sein und ist zu kontrollieren aber zumindest das 
Bitgefummel und auseinanderpfriemeln fällt beim Kontrollieren weg.

von Karl H. (kbuchegg)


Lesenswert?

wenn du dier diesen Code
1
  while(1)
2
  {
3
    if (sekunde==2)
4
    {
5
    PORTD|=(1<<PD7);
6
      if (sekunde==4)
7
      {
8
      PORTD&=~(1<<PD7);
9
      }
10
    }
11
  }

sauber einrückst, dann sieht er so aus
1
  while(1)
2
  {
3
    if (sekunde==2)
4
    {
5
      PORTD|=(1<<PD7);
6
      if (sekunde==4)
7
      {
8
        PORTD&=~(1<<PD7);
9
      }
10
    }
11
  }

und da erhebt sich sofort eine Frage:
Das obere if führt seinen then Teil nur dann aus, wenn sekunde gleich 2 
ist. Innerhalb dieses if steht das andere if, bei dem sekunde gleich 4 
sein müsste. Nur: Wie kann das sein? An dieser Stelle steht schon fest, 
dass sekunde gleich 2 sein muss, andernfalls wäre das Programm nie an 
diese Abfrage gekommen! An dieser Stelle KANN sekunde daher niemals 4 
sein was wiederrum bedeutet, dass dein Port einmal eingeschaltet aber 
nie wieder ausgeschaltet wird.

Du hast überhaupt eine seltsame Art der Einrückung, wie man innerhalb 
der ISR sieht.
Die Einrückung dient nicht dazu, nach Gutdünken angewendet zu werden, 
sondern sie hat eine Funktion! Sie zeigt welcher Code abhängig von 
welchem anderen Code ist.
Daher: Nach einem { wird eingerückt. Das zugehörige } wird wieder 
ausgerückt. Und ein paar strategisch platzirete Leerzeichen dann und 
wann machen den Code leichter lesbar. Schliesslich bist du von 
Kindesbeinen an daran gewöhnt worden, dass zwischen Wörtern ein 
Leerzeichen kommt. Oder findestduetwdiesenTextwirklichlesbarer als wie 
wenn zwischen den Wörtern ein Zwischenraum steht?
1
ISR (TIMER2_COMP_vect)
2
{
3
  millisekunde++;
4
  if (millisekunde == 1000)
5
  {
6
    millisekunde = 0;
7
    sekunde++;
8
  }
9
10
  if (sekunde == 60)
11
  {
12
    sekunde = 0;
13
     minute++;
14
  }
15
16
  if (minute == 60)
17
  {
18
    minute = 0;
19
    stunde++;
20
  }
21
}

von Karl H. (kbuchegg)


Lesenswert?

Bei solchen Sachen bin ich zwiespältig
1
int main(void)
2
{
3
4
INITIALISIERUNG_SYSTEMPORTS();          //Ports initialisieren

Das Problem:
Die Initialisierung der Ports sind maximal ein paar Zuweisungen an die 
DDR Register und eventuell das Setzen von Pullups. Das ist aber eine 
wichtige Information, die ich nicht wirklich in eine eigene Funktion 
verpacken würde. Denn um in deinem Programm zu kontrollieren, ob du PD7 
auch wirklich auf Ausgang gesetzt hast, muss ich jetzt in eine andere 
Funktion wechseln um mir das anzusehen.

Fängt dein Programm so an
1
int main(void)
2
{
3
  DDRD = ( 1 << PD7 );

dann ist das auch nicht länger als der Funktionsaufruf, ich sehe aber 
auf einen Blick, dass du PD7 auf Ausgang gesetzt hast und zwar NUR PD7. 
All das sehe ich nicht bei deinem Funktionsaufruf (der aus welchen 
Gründen auch immer in seiner SChreibweise eigentlich ein Makro ist, was 
in mir sowieso schon wieder die nächsten Alarmglocken zum klingeln 
bringt)

von Matze (Gast)


Lesenswert?

Hallo Danke für die schnell Antwort,
also habe den Code mal um geschrieben:


  while(1)
  {
    if (sekunde==2)
    {
      PORTD|=(1<<PD7);
    }
    if (sekunde==4)
    {
       PORTD&=~(1<<PD7);
    }
  }
}

müsste so jetzt passen oder?

und zu karl heinz,

TCCR2=0b00001100;
//CTC Mode, Prescaler=64  (16MHz/64=250KHz ->  250KHz=4µs)

OCR2=250-1;
//TCNT 2 wird mit vorgeteilter Frequenz (250KHz bzw.alle 
4µs)inkrementiert,
bis OCR2-1(-1, da das Interrupt Flag erst einen Timertakt nach der 
Übereinstimmung gesetzt wird) erreicht wird (4µs*250=1ms) dann startet 
ISR Timer2

von Matze (Gast)


Lesenswert?

Port D wird folgender Maßen initialisiert:

DDRD |= (1<<PD7);
PORTD &= ~(1<<PD7);
//PortD
//Datenrichtungsregister von PortD Pin 7 wird als Ausgang definiert.
//Setze Pin 7 auf "low".

von Karl H. (kbuchegg)


Lesenswert?

Matze schrieb:

> müsste so jetzt passen oder?

Versuch macht kluch

> TCCR2=0b00001100;
> //CTC Mode, Prescaler=64  (16MHz/64=250KHz ->  250KHz=4µs)

Kann alles sein. Ich weiß ja nicht, welchen µC du benutzt daher kann ich 
das auch nicht kontrollieren.

von Matze (Gast)


Lesenswert?

Aso ja sorry,
also Code funktioniert so wie ich ihn gepostet habe.
Ich benutze einen AtMega 32.

PS.:Habe den Fehler jetzt gefunden. in den Einstellungen des AVR Studios 
war der AtMega 16 mit 1Mhz eingestellt.

Danke an euch und ich freue mich über Anregungen um meine Code 
übersichtlicher und schneller lesbar zu machen.

MfG.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.