www.mikrocontroller.net

Forum: Compiler & IDEs Atmega32 und Timer0 funktioniert nicht


Autor: NoName (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
will gerade den Timer0 beim Atmega32 programmieren.
Es klappt jedoch nicht so wie ich will.
Mein Atmega taktet mit 16.000 Mhz

Hier mal mein Quellcode:
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
//--------------------------

volatile unsigned int timer = 0;

ISR(TIMER0_OVF_vect)
{
   timer++;
   if(timer>= 20)
   {
      PORTA = ~PORTA; //Leds invertieren
   }
   TCNT2 = 0;
}

int main (void)
{
  DDRA = 0xff;
  PORTA = 0xff;

  TCCR2 = (1<<CS02) | (1<<CS00);
  TCNT2  = 0;
  TIMSK = (1<<TOIE0);

  sei();

  while(1)
  {  
    
  }
  return(0);    
}

Ich weis nicht wo der Fehler ist. Aber irgendwie wollen die Leds nicht 
blinken. Sie gehn einfach nur an.

Danke für eure Hilfe

Autor: Lord Ziu (lordziu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
NoName schrieb:
> PORTA = ~PORTA; //Leds invertieren

PORTA = PINA;

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
NoName schrieb:
> Ich weis nicht wo der Fehler ist.

Du startest Timer 2, nicht 0.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltes dich mal entscheiden, ob du nun mit Timer0 oder mit Timer2 
arbeiten willst.

Und wenn dann deine ISR mal öfter aufgerufen wird, musst du schon 
abwarten, bis die Variable timer überläuft. Erst dann wird die wieder 
kleiner als 20.

Oliver

Autor: NoName (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
ich weis nicht wieso ich da immer den Timer2 genommen habe.
Danke aufjedenfall.

Hier nochmal der funktionierende Quelltext:
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
//--------------------------

volatile unsigned int timer = 0;


ISR(TIMER0_OVF_vect)
{
   timer++;
   if(timer>= 100)
   {
     PORTA = ~PORTA;
     timer=0;
   }
   TCNT0 = 0;
}

int main (void)
{
  DDRA = 0xff;
  PORTA = 0xff;

  TCCR0 = (1<<CS02) | (1<<CS00);
  TCNT0  = 0;
  TIMSK = (1<<TOIE0);

  sei();

  while(1)
  {  
    
  }
  return(0);    
}

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du dir jetzt noch mal Gedanken über das
 TCNT0 = 0; 
 in der ISR machst, und dabei rekapitulierst, wann ein "Timer Overflow 
Interrupt" ausgelöst wird, wird es noch besser.

Oliver

Autor: NoName (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das brauch ich dann nicht weil es dann so oder so wieder auf null geht?

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
NoName schrieb:
> das brauch ich dann nicht weil es dann so oder so wieder auf null geht?

So oder so ähnlich...

Oliver

Autor: NoName (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja ist doch so:

 11111111 <- 255
100000000 <- Overflow und das 8te Bit fällt weg
 00000000 -> entspricht 0

oder irre ich mich da?

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

Bewertung
0 lesenswert
nicht lesenswert
NoName schrieb:
> ja ist doch so:
>
>  11111111 <- 255
> 100000000 <- Overflow und das 8te Bit fällt weg
>  00000000 -> entspricht 0
>
> oder irre ich mich da?

Nein, du irrst dich nicht.

Generell: Lass den Timer in Ruhe arbeiten. Pfusche ihm nicht am 
Zählerstand rum.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
NoName schrieb:
> oder irre ich mich da?

Nein. In deinem Programm ist das so, daß de Timer an der Stelle, wo du 
ihn manuell auf 0 setzt, schon von selber 0 ist. Da schadet dein 
Nullsetzen nicht, es nutzt aber auch nichts.

Wenn du aber irgendwann mal ein ähnliches Programm schreibst, in dem der 
Timer mit einer schnelleren Taktrate arbeitet, könnte der bis zu dem 
manuellen Nullungsbefehl schon wieder bis 1, 2, oder noch weiter gezählt 
haben. Wenn du den dann manuell auf Null setzt, stimmt das Timing nicht 
mehr. Daher, wie Karl Heinz schon schrieb, lass den Timer Timer sein. 
Der macht das schon.

Oliver

Autor: NoName (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, danke für den tip.

ich habe mal mein programm erweitert.
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
//--------------------------

volatile unsigned int timer = 0;
volatile unsigned int adwert = 0;

void wait(unsigned int time)
{
   timer = 0;
   while(timer<time)
   {
   }
}

ISR(ADC_vect)
{
  adwert = ADCH;
  ADCSRA = 0xC8;
}

ISR(TIMER0_OVF_vect)
{
   timer++;
}

int main (void)
{
  DDRA = 0xff;
  PORTA = 0xff;

  TCCR0 = (1<<CS02) | (1<<CS00);
  TCNT0 = 10;
  TIMSK = (1<<TOIE0);

  ADMUX = 0x24;
  SFIOR = 0x00;
  ADCSRA = 0xC8;

  sei();

  while(1)
  {  
  wait(adwert);
  PORTA = ~PORTA;
  }
  return(0);    
}

Jedoch verhält sich das Programm komisch.
Die wait Funktion klappt mit festen werten und auch der AD-Wandler 
klappt alleine.

Autor: NoName (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
ich glaub heute ist nicht mein tag.
wenn man zwei quelltexte kopier ist nicht so gut habe ich gerade 
festgestellt....

ich habe vergessen den AD Port als eingan zu definieren, jetzt tuts...

Danke jetzt klappt alles was ich wollte

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

Bewertung
0 lesenswert
nicht lesenswert
void wait(unsigned int time)
{
   timer = 0;
   while(timer<time)
   {
   }
}

so einfach ist die Sache nicht.
Da timer eine 16 Bit Variable ist, muss der µC alle Zugriffe auf diese 
Variable in 2 Häppchen erledigen. Und zwischen diesen beiden Häppchen 
sollte dir tunlichst kein Interrupt dazwischenfunken, sonst gibts 
Datensalat.
void wait(unsigned int time)
{
   unsigned int now;

   cli();
   timer = 0;
   sei();

   do {
     cli();
     now = timer;
     sei();
   } while( now < time );
}

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.