www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik CTC bei ATTINY2313 8 Bit Timer0


Autor: Thomas Webster (ram99)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Ich bekomme mein Timer0 mit dem CTC nicht zum laufen. Kann mir jemand 
sagen wo hier das Problem ist. Laut Datenblatt sind die Register und der 
Interrupt-Vector richtig wenn ich es verstanden habe :)
Der Port B sollte nach ~ 7,8 sek auf 1 gehen.

#define F_CPU 4000000UL

#include <stdio.h>
#include <avr\io.h>
#include <avr\interrupt.h>

int Teiler;


// ISR( TIMER0_OVF_vect )   // Interrupt Overflow Aufruf Timer 0

ISR( TIMER0_COMPA_vect )   // Interrupt Compare A Aufruf Timer 0
{
  Teiler++;
  if( Teiler == 1000 )
  {
    Teiler = 0;
    PORTB = 0xFF;
  }
}


int main()
{
  DDRB = 0xff;     // Setze Port B als Ausgang
  PORTB = 0x00;    // Port B auf 0 setzen

  Teiler = 0;

  TCCR0A |= (1<<WGM01);        // Aktiviere CTC zum OCR0A Werte vorgeben
  TCCR0B |= (1<<CS00 | 1<<CS02);   // Setze Counter 0 prescaler 1024
  TIMSK |= (1<<TOIE0);        // Aktiviere Overflow Interrupt für 
Counter 0
  OCR0A = 128;                     // Wert für CTC

  sei();                 // Aktiviere Interrups allgemein

  while( 1 )
  {
  }
}

Autor: Otto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Thomas,

das "volatile" für "Teiler" fehlt z.B.

Gruss Otto

Autor: Thomas Webster (ram99)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Otto wrote:
> Hallo Thomas,
>
> das "volatile" für "Teiler" fehlt z.B.
>
> Gruss Otto

Hallo Otto,
habe jetzt "volatile int Teiler;" eingefügt aber es möchte noch immer 
nicht funktionieren.

Gruss Thomas

Autor: Axel R. (axelr) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kannnicht

>  TIMSK |= (1<<TOIE0);        // Aktiviere Overflow Interrupt für

Du musst den Comparematch Interrupt aktivieren

Gruß
/XlR.

Autor: Thomas Webster (ram99)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel Rühl wrote:
> kannnicht
>
>>  TIMSK |= (1<<TOIE0);        // Aktiviere Overflow Interrupt für
>
> Du musst den Comparematch Interrupt aktivieren
>
> Gruß
> /XlR.


Upps, danke das wars. Hatte davor den Timer mit Overflow versucht und 
das total übersehen. Mir fehlt aber auch noch ein bisschen die 
Erfahrung. Sind momentan meine ersten Versuche.

Ab wann muss man den seine Variablen mit "volatile" deklarieren ?

Gruss  Thomas

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

Bewertung
0 lesenswert
nicht lesenswert
> Ab wann muss man den seine Variablen mit "volatile" deklarieren ?

volatile musst du dann nehmen, wenn Gefahr besteht, dass
der Compiler einen Zugriff auf die Variable wegoptimieren
könnte. Grob gesagt: Immer dann, wenn es für den Compiler
nicht ersichtlich ist, dass eine Variable auf anderen
Wegen als die die dem Compiler bekannt sind einen neuen
Wert kriegt.

volatile macht nichts anderes, als einfach nur mögliche
Optimierungen auf dieser Variablen abzuschalten.

Bsp:

du hast folgende Schleife

unsigned char i;
unsigned char a;

void foo()
{
   i = 0;

   while( i == 5 ) {
      a = 8;
   }
}

Wenn der Compiler diese Funktion übersetzt, dann findet die
Datenflussanalyse heraus, dass i zu Beginn der Schleife
den Wert 0 hat. Weiters findet die Analyse heraus, dass
es innerhalb der Schleife keine Möglichkeit für i gibt,
je verändert zu werden. Da i daher immer den Wert 0 hat,
kann die Schleife niemals betreten werden und kann damit
komplett wegfallen.

Nur: Jetzt kommt dein Programmund installiert einen Interrupt-
handler, welcher - Überraschung - sehr wohl i irgendwann mal
auf 5 setzt.

Nur: Das weis der Compiler nicht, wenn er foo() übersetzt.

Also muss man ihm mitteilen: Spar dir Optimierungen, die über
i laufen. i ändert seinen Wert auf Wegen die für dich nicht
einsehbar sind.

Und genau das macht das volatile

volatile unsigned char i;

Jetzt trifft der Compiler keinerlei Annahmen mehr über i.
Er speichert den Wert der Variablen auch nicht in einem
CPU Register zwischen, wie zb hier:

    j = i + i;

sondern liest bei jeder Erwähnung von i den Wert tatsächlich
aus dem Speicher aus. (Im obigen wäre das ja eigentlich unsinnig.
Speicher auslesen kostet Zeit. Wenn der Compiler i einmal holt
und dann verdoppelt kommt das gleiche raus)

Leider verkommt volatile bei vielen Programmierern zu:
Wenn du in einem ISR eine Variable benutzt, muss diese
volatile sein.
Unsinn. Jetzt weist du was wirklich dahinter steckt.

In deinem Pgm hast du den Fall aber nicht, selbst wenn
der ISR-Vektor richtig gestellt ist. Da Teiler eine globale
Variable ist, wird die vom Compiler sowieso mit 0 initialisiert.
Die Zuweisung von 0 in main() bewirkt also im Grunde genommen
gar nichts. Damit kommt Teiler aber nur noch in der ISR vor
und damit besteht die Gefahr gar nicht.

Autor: the_devil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz Buchegger

Danke, eine bessere Erklärung für "voaltile" habe ich no nie 
bekommen....
Respekt

Autor: the_devil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ähhh...volatile

Autor: Reedemer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tach ich bin Hier neu und Wollte Fragen wie ich meinen Counter Aktiviere 
also das man ihn sieht und er auch schön Zählt

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.