Forum: Mikrocontroller und Digitale Elektronik Timer0 fuer anfänger


von Axel (Gast)


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

von Stefan B. (stefan) Benutzerseite


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")

von Axel (Gast)


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?

von Guest (Gast)


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 ...

von Jean P. (fubu1000)


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ß

von Stefan B. (stefan) Benutzerseite


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!

von Axel (Gast)


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

von Jean P. (fubu1000)


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ß

von Jean P. (fubu1000)


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ß

von Axel (Gast)


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

von Jean P. (fubu1000)


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ß

von Axel (Gast)


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.

von Axel (Gast)


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

von Karl H. (kbuchegg)


Lesenswert?

ISR(TIMER0_OVF_vect)
{
 volatile counter = 0;

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

von Jean P. (fubu1000)


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++;
> }

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.