Forum: Compiler & IDEs töne in c mit interrupt am attiny2313


von jr (Gast)


Lesenswert?

hi,
als newbie verstehen ich das verhalten des interrupts am timer nicht - 
kann man den nicht IN einer function aufrufen??
konkret: das progi melodie macht 2 töne, das prog melodieinterrupt lässt 
den lautsprecher VIEL zu langsam ticken...
wer weiss was?
danke
jürgen

von Ronny (Gast)


Lesenswert?

Welchen Interrupt meinst du denn?Da gibt es nämlich mehrere.Z.b einen 
wenn der Timer überläuft und einen anderen wenn wenn an einem bestimmten 
Pin ein Flankenwechsel erkannt wird.

Und nein,einen Interrupt kann man so ohne weiteres nicht einfach 
aufrufen.In Assembler kann man von Hand mit einigen Tricks in den 
Interrupt-Code springen,aber in C ist das nicht so ohne weiteres 
machbar.

Lies dir doch mal die Tutorials hier auf der Seite durch.sind zwar für 
einen der Mega-AVR-Typen,aber die Grundlagen wie Interrupt-Handling ist 
auf allen AVR-Typen gleich.

von Karl H. (kbuchegg)


Lesenswert?

Beschreib dein Problem genauer.

> als newbie verstehen ich das verhalten des interrupts am timer
> nicht - kann man den nicht IN einer function aufrufen??

Ein Interrupt (Unterbrechung) wird bei dieser Hardware
von der Hardware ausgelöst. Aber es hindert einen nichts
und niemand die Funktionalität die bei einem Interrupt
passieren soll in eine Funktion auszulagern. Diese
Funktion wird dann von einem Interrupt Handler aufgerufen
und kann natürlich auch von überall anders aufgerufen
werden.

Aber ich denke das ist für dein eigentliches Problem
nicht sehr hilfreich.

> konkret: das progi melodie macht 2 töne

Welches progi melodie?
Das kennt hier keiner.

von jr (Gast)


Lesenswert?

ich habe im formular die rubrik "dateianhang" wohl missverstanden - 
deshalb hier die beiden programme:
melodie OHNE interupt
#include <avr\io.h>
#include <avr\interrupt.h>
int main()
{   DDRB = 0xFF;   // B ist OutPut
  void ton(int freq,int dauer)
  {int t=0;int i;int a ;
  for (i=0;i<dauer;i++)
  {PORTB=t;t++;a=0;while (a<freq){a++;};};
  }
  while (2==2)  {ton(500,1000);ton(250,1000);}
  return 1;}

melodie MIT interrupt
#include <avr\io.h>
#include <avr\interrupt.h>
#include <avr/signal.h>
volatile int i=0;
SIGNAL (SIG_TIMER0_OVF){ i++;}

void ton(int freq,int dauer)
  {int t=0;int k;
  for (k=0;k<dauer;k++)
  {PORTB=t;t++;i=0;while (i<freq){};};  }
int main()
{ DDRB = 0xFF;   // B ist OutPut
  TCCR0B |= (1 << CS02) | (1 << CS00); //Prescaler auf 1024 stellen
  TIMSK  |= (1 << TOIE0);              // Timer 0 Overflow Interrupt 
enable
  sei(); // Interrupts einschalten
while (2==2)  {ton(5,100);ton(2,100);}
return 1;}

bei 12MHz takt ist prescale 1024 ca 12khz, also müsste i auf mindestens 
10 hochzählen, damit die pausen zwischen den lautsprecherticks an PORTB0 
ungefähr 1200Hz entsprechen - das passt in realität aber nicht, statt 
des lautsprechers angeschlossene led blinkt nur träge vor sich hin...

jürgen







von Karl H. (kbuchegg)


Lesenswert?

> bei 12MHz takt ist prescale 1024 ca 12khz, also müsste i auf
> mindestens 10 hochzählen, damit die pausen zwischen den
> lautsprecherticks an PORTB0 ungefähr 1200Hz entsprechen

Ich denke du hast vergessen, dass der Timer zwischendurch
auch noch bis 256 zählen muss, damit der Overflow
auftritt. Kein Wunder dass dein Timing nicht stimmt.

12 Mhz                    12000000
Prescaler 1024               11718
bis 256 zählen                  45 Overflows / Sekunde
Warten bis 10 Overflows          4.5  Ereignisse / Sekunde

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.