Timer0 fuer anfänger

Gast #1701995
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
Persönliche Seite #1702021
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")
Gast #1702032
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?
Gast #1702040
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 ...
#1702046
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ß
Persönliche Seite #1702053
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!
#1702067
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ß
#1702071
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ß
Gast #1702090
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
Gast #1702107
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren