Forum: Compiler & IDEs Atmega8 Timer/Interrupt Schwierigkeiten


von Arne(Anfänger) (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
also ich habe die ganze Zeit die Suchfunktion betätigt aber ich finde 
dabei nicht den Fehler in einem kleinem Programm.
Ich wollte mal gerne einen Timer0 mit dem setzen eines Interrupts 
ausprobieren. Jedoch verstehe ich nicht ganz ob ich den TCNT0 
vordefinieren muss oder nicht.
Also das Programm lässt sich im AVR Studio linken und auch zum Atmega8 
übertragen, aber ich befürchte ich habe da noch ein grundsätzliches 
Verständnisproblem.
Ich wäre sehr Dankbar wenn sich kurz einer die Zeit nehmen würde und mir 
den rechten Weg weisen würde ;)
Liebe Grüße Arne

von Karl H. (kbuchegg)


Lesenswert?

Arne(Anfänger) schrieb:

> Ich wollte mal gerne einen Timer0 mit dem setzen eines Interrupts
> ausprobieren. Jedoch verstehe ich nicht ganz ob ich den TCNT0
> vordefinieren muss oder nicht.

Nein. musst du nicht.
TCNT0 ist das Register in dem die Hardware zählt.
Wenn du also dieses Register beobachten würdest, würde es ständig seinen 
Wert ändern - es zählt hoch.
Sobald der Timer einen Vorteiler eingestellt bekommt, zählt er in TCNT0.
That's it. Mehr gibt es (momentan) dazu eigentlich nicht zu sagen.

> Also das Programm lässt sich im AVR Studio linken und auch zum Atmega8
> übertragen, aber ich befürchte ich habe da noch ein grundsätzliches
> Verständnisproblem.

Woraus schliesst du das?

> Ich wäre sehr Dankbar wenn sich kurz einer die Zeit nehmen würde und mir
> den rechten Weg weisen würde ;)

Das ist schon ok so.


Zum Programm:
Gewöhn dir von Anfang an gleich an, nach Möglichkeit immer korrektes 
Standard-C zu benutzen. In C gibt es keine Möglichkeit in einer Funktion 
eine andere Funktion zu definieren. main() ist eine Funktion und die ISR 
ist auch eine Funktion. Daher kann die ISR nicht innerhalb von main() 
definiert werden, sondern ist eine eigenständige Funktion ausserhalb von 
main()
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
volatile unsigned int  millisekunden=0;
5
volatile unsigned int  sekunde=0;
6
7
ISR (TIMER0_OVF_vect)       // Timer0 overflow Interrupt
8
{
9
  millisekunden++;
10
11
  if(millisekunden==1000)
12
  {
13
    sekunde++;
14
    millisekunden=0;
15
  }
16
}
17
18
int main()
19
{                  // IO konfigurieren
20
  DDRC=0x00;
21
  DDRD=0xff;
22
23
                     // Timer0 konfigurieren
24
  TCCR0 =(1<<CS02)|(1<<CS01);
25
  TIMSK |= (1<<TOIE0);      // Timer Overflow Interrupt freischalten
26
27
  sei();              // Interrupts freigeben
28
  while(1)             // Endlose Hauptschleife
29
  {
30
    if(sekunde==1)
31
    {
32
      PORTD|=(1<<PD5);
33
      PORTD|=(1<<PD6);
34
    }
35
  }
36
37
  return 0;
38
}

Und achte auch auf deine Codeformatierungen. Ich finde es immer wieder 
spannend, dass Neulinge gerne jede Zeile in einer Wurscht dahinschreiben 
aber anscheinend als Ausgleich dafür jede Menge Leerzeilen einfügen. Die 
Leerzeilen bringen nichts, ausser dass sie den Code in die Länge ziehen. 
Aber ein paar Leerzeichen zwischen den "Wörtern" würden den Lesefluss 
erheblich vereinfachen. Denn schliesslich sind wir alle von Kindesbeinen 
darauf trainiert worden, dass zumindest im Deutschen zwischen den 
Wörtern ein Leerraum steht und nicht einfach nur alle Buchstaben 
aneinandergefügt werden.
1
ISR (TIMER0_OVF_vect)       // Timer0 overflow Interrupt
2
{
3
  millisekunden++;
4
5
  if( millisekunden == 1000 )
6
  {
7
    sekunde++;
8
    millisekunden = 0;
9
  }
10
}

von Karl H. (kbuchegg)


Lesenswert?

Hab ich ganz vergessen

> aber ich finde
> dabei nicht den Fehler in einem kleinem Programm.

Wie macht sich der Fehler bemerkbar?

"Geht nicht" ist so ziemlich die nichtssagenste Problembeschreibung, die 
du machen kannst.

von Arne(Anfänger) (Gast)


Lesenswert?

Wenn ich soviel überflüssige  Zeilen einfüge hoffe ich, dass es ein 
bisschen übersichtlicher ist. Aber ich werde mir das fix wieder 
abgewöhnen und dafür Leerzeichen einfügen ;)
Ich habe die ISR Funktion nun vor dir main() geschrieben.
Beim übertragen des Programmes habe ich mal einen Ausgang gesetzt und 
wieder gelöscht. Somit schließe ich einen Hardwarefehler aus, da die LED 
an und aus ging.

Die  Ausgänge PD5 und PD6  kommen leider nicht nach der gewünschten Zeit 
so wie ich es programmiert habe. Also schließe ich daraus, dass meine 
Programm einen oder mehrere Fehler hat.
Oder könnte das noch was anderes sein??

von Karl H. (kbuchegg)


Lesenswert?

Arne(Anfänger) schrieb:

> Die  Ausgänge PD5 und PD6  kommen leider nicht nach der gewünschten Zeit
> so wie ich es programmiert habe. Also schließe ich daraus, dass meine
> Programm einen oder mehrere Fehler hat.
> Oder könnte das noch was anderes sein??

Noch mal ins Datenblatt schauen, was die Einstellung

  (1<<CS02)|(1<<CS01);

beim Timer 0 bewirkt.
Das ist die Einstellung für externe Taktquelle. Solange du keinen 
externen Takt am Pin T0 an den Prozessor anlegst, fehlt dem Timer 
schlicht und ergreifend der Anreiz zu zählen :-)

> Wenn ich soviel überflüssige  Zeilen einfüge hoffe ich, dass es ein
> bisschen übersichtlicher ist.

Wenn du Übersicht willst, dann mach einen Blockkommentar anstatt unnötig 
vieler Leerzeilen :-) Im Blockkommentar beschreibt man, worum es im 
nächsten Abschnitt geht, welche Überlegungen dahinter stecken, etc. Auch 
das gliedert den Code in Blöcke
1
int main()
2
{
3
  //
4
  // IO konfigurieren
5
  //
6
  DDRC = 0x00;
7
  DDRD = 0xff;
8
9
  //
10
  // Timer0 konfigurieren:
11
  //    Vorteiler: 1024
12
  //    Overflow Interrupt ein
13
  // Das ergibt bei 1Mhz Taktfrequenz einen Overflow-Frequenz von
14
  // 1000000 / 1024 / 256 = 3.81 Hz
15
  // bzw.  einen Interrupt alle  1 / 3.81 = 0.26 Sekunden
16
  //
17
  TCCR0  = (1 << CS02) | (1 << CS00);  // Vorteiler 1024
18
  TIMSK |= (1 << TOIE0);               // Timer Overflow Interrupt freischalten
19
20
  sei();               // Interrupts freigeben
21
22
  //
23
  // Alles fertig konfiguriert ...
24
  // ... und los gehts!
25
  //
26
  while(1)

von Arne(Anfänger) (Gast)


Lesenswert?

Ohh hammer es funktioniert....mein Tag ist gerettet.
Vielen Danke für Ihre Hilfe.
Der Fehler lag wirklich in der falschen programmierung von CS1..dabei 
dachte ich die ganze Zeit das ich CS0 geschrieben habe.. Irgendwie 
fehlte mir der Blick-

vielen Danke
MFg Arne

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.