mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer0 fuer anfänger


Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich benutze ein Atmega32  mit STK600.
Als neuling , wolte ich dem Timer0 probieren. Ich wolte meine LED auf 
PortB umschalten. Umschaltzeit sollte normalweise bei ca. 30s liegen . 
Aber es tut gar nicht.
 Ich habe wie steht in der Tutorial gemacht.
Meine Led bleiben einfach und ständig an.

Hier mein Code.  Kann jemandem mir weiter helfen?

#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>
#include <avr/interrupt.h>




ISR(TIMER0_OVF0_vect)
{
 PORTB=~PORTB;
}


int main (void)

{
// Initialisation

DDRB  = 0xFF;                 // Set Port B as output

TCCR0 = (1<<CS02)|(1<<CS00);  // set Timer Clock = system clock / 1024
TIMSK = 1<<TOIE0;        // Enable Timer Conuter0 Overflow Interrupt

sei();
while(1);




}

danke

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel schrieb:

> Als neuling , wolte ich dem Timer0 probieren. Ich wolte meine LED auf
> PortB umschalten. Umschaltzeit sollte normalweise bei ca. 30s liegen .

30s, hmm, wie kommst du auf den Wert?

Bei einem "langsam" getakteten Atmega32 mit 1 MHz (Werkseinstellung) 
komme ich bei deinem Code schon auf kurze 1/(1000000/1024/256) = 0,26 s. 
Wenn du schneller taktest entsprechend kürzer, eventuell so kurz, dass 
du statt Blinken ein Dauerleuchten siehst (Blinkzeit kleiner ca. 0,04 s 
"25 Bilder/s")

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,

ja, du hast rechts rechnenfehler.
so komme ich auf die werte: 16 MHZ/1024= 15625 /256(overflow time bei 8 
bits Zähler)  = 61s/2  (on/off zeit)=30/s.

Also es ist 30x pro/s. Bestimmt ist das zu schnell für die augen. Wie 
kann ich das runterkriegen?

Autor: Guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie kann ich das runterkriegen?

In der ISR eine Variable hoch- oder runterzählen und bei einem 
bestimmten Wert eine Aktion durchführen.
Bei der Deklaration der Variablen das "volatile" nicht vergessen ...

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel schrieb:
> ISR(TIMER0_OVF0_vect)
> {
>  PORTB=~PORTB;
> }

Hmm, müsste es nicht heissen :  ISR(TIMER0_OVF_vect) ?

>Also es ist 30x pro/s. Bestimmt ist das zu schnell für die augen. Wie
>kann ich das runterkriegen?

volatile counter = 0;
ISR(TIMER0_OVF0_vect)
{
  PORTB = counter > 1000 ? 0xFF : 0x00;
  counter = counter > 2000 ? 0 : counter+1;
}

Gruß

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast mehrere Möglichkeiten

1/ Zusätzlicher Softwareteiler

#define SOFTWARE_PRESCALER (30*((16000000/1024)/256))

ISR(TIMER0_OVF0_vect)
{
  static uint16_t software_prescaler = 0;
  if ( ++software_prescaler == SOFTWARE_PRESCALER )
  {
    PORTB = ~PORTB;
    software_prescaler = 0;
  }
}

2/ Timer mit mehr Schritten, also statt 8-Bit (256) 16-Bit (65536)
und CTC Modus siehe AVR-GCC-Tutorial/Die Timer und Zähler des AVR

EDIT:

>> Hmm, müsste es nicht heissen :  ISR(TIMER0_OVF_vect) ?

Unbedingt prüfen!

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,






Jean Player schrieb:
> PORTB = counter > 1000 ? 0xFF : 0x00;
>   counter = counter > 2000 ? 0 : counter+1;

ich möchte gern  die folgenden code line verstehen.

danke

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jean Player schrieb:
> volatile counter = 0;
> ISR(TIMER0_OVF0_vect)
> {
>   PORTB = counter > 1000 ? 0xFF : 0x00;
>   counter = counter > 2000 ? 0 : counter+1;
> }
>
> Gruß

Mist da muss ich selbst zitieren ;-)
Habe durch copy&paste den ISR(TIMER0_OVFO_vect reinbekommen.
Sollte heissen:

...
volatile counter = 0;
...

ISR(TIMER0_OVF_vect)
{
  PORTB = counter > 1000 ? 0xFF : 0x00;
  counter = counter > 2000 ? 0 : counter+1;
}

Gruß

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel schrieb:
> ich möchte gern  die folgenden code line verstehen.

Kein Problem.

//PORTB wird auf 0xFF gesetzt, wenn counter grösser 1000, ansonsten auf 
0x00
PORTB = counter > 1000 ? 0xFF : 0x00;

//counter auf NULL setzen, wenn grösser 2000, ansonsten counter + 1
counter = counter > 2000 ? 0 : counter+1;

Also ist die Hälfte der Zeit PORTB 0xFF und die andere Hälfte 0x00.
Und bei nicht verstehen, suche mal nach Frage Zeichen Operator.

Gruß

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Jean Player,


kann ich auch so schreiben?


volatile counter = 0;
ISR(TIMER0_OVF0_vect)
{

 if (counter>1000)
  {PORTB =0xff;}
  else
  {PORTB=0x00;}

  if (counter>2000)
     {counter=0;}
   else
   counter++;
}
so ist es übersichlicht für mich.
oder übersehe ich was

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Axel,
ja dein letzter Code entspricht meinem, nur halt länger.
ABER , prüfe doch noch mal bitte folgende Zeile: ISR(TIMER0_OVF0_vect)
ICH meine (könnte auch falsch sein, ausm Gedächtnis) es müsste 
ISR(TIMER0_OVF_vect) heissen.

Gruß

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Stefan,

Stefan B. schrieb:
> Hmm, müsste es nicht heissen :  ISR(TIMER0_OVF_vect) ?

es ist die richtige Version

Stefan B. schrieb:
> 2/ Timer mit mehr Schritten, also statt 8-Bit (256) 16-Bit (65536)
> und CTC Modus siehe AVR-GCC-Tutorial/Die Timer und Zähler des AVR

Welche  von beiden ist das beste, efahrungsgemäß?

Schaue ich mal nach.

vielen Dank fuer deine Tipp.

Autor: Axel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

ich habe der komplett code hier, aber es tut nichts. Die LED bleiben an. 
Keine on/off.

Dle LED sin direkt an PORTB  angeschloßen. Vielleicht tue ch da was 
falsches.


#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>
#include <avr/interrupt.h>


ISR(TIMER0_OVF_vect)
{
 volatile counter = 0;

  if (counter>1000)
  {PORTB =0xff;}
  else
  {PORTB=0x00;}

  if (counter>2000)
     {counter=0;}
   else
   counter++;
}


int main (void)

{
// Initialisation

DDRB  = 0xFF;                 // Set Port B as output

TCCR0 = (1<<CS02)|(1<<CS00);  // set Timer Clock = system clock / 1024
TIMSK = 1<<TOIE0;        // Enable Timer Conuter0 Overflow Interrupt

sei();
while(1);

}

Jetzt probier ich dem Software version von Stefan

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

Bewertung
0 lesenswert
nicht lesenswert
ISR(TIMER0_OVF_vect)
{
 volatile counter = 0;

das volatlile muss static heissen
ISR(TIMER0_OVF_vect)
{
  static int counter = 0;

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
oder er macht sein volatile global !

>volatile counter;
>
> ISR(TIMER0_OVF_vect)
> {
>   if (counter>1000)
>   {PORTB =0xff;}
>   else
>   {PORTB=0x00;}
>
>   if (counter>2000)
>      {counter=0;}
>    else
>    counter++;
> }

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.