www.mikrocontroller.net

Forum: Compiler & IDEs pwm am atmega8


Autor: Philipp Karbach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
versuche gerade pwm zu verstehen und zu benutzen. Folgender code soll
auf einem mega32 ein step-up licht erzeugen:

#include <avr/io.h>
#include <avr/delay.h>

int main (void)
{
  DDRB=0xff;
  PORTB=0x00;
  int i;

  TCCR0 = (_BV(WGM00) | _BV(COM01) | _BV(COM00) | _BV(CS00));
  while(1)
   {for (i=0;i<255;i=i+1)
     {OCR0=i;
      _delay_loop_2(20000);}}
}

Ich habe allerdings einen mega8. Ich weiß dass ich zum beispiel den
Ausgang ändern muss, weil es OCR0 beim Mega8 nicht gibt aber wie muss
ich den Timer einstellen? Vielen Dank!

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Statt Timer0 mußt du den Timer2 nehmen. Prinzipiell sieht die
Konfiguration gleich aus, nur daß halt überall die Null hinter dem
Namen durch eine 2 ersetzt werden muß (TCCR0 -> TCCR2, WGM00 -> WGM20,
OCR0 -> OCR2 u.s.w.)

Autor: Philipp Karbach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke das klappt jetzt, nur warum? ist das nur ne namenssache oder gibt
es da noch einen unterschied?

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

Bewertung
0 lesenswert
nicht lesenswert
> nur warum?

Das übliche:
Besorg die bei www.atmel.com die Datenblätter der beiden µC
und vergleiche selbst.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist übrigens genau das, was ich getan habe, um die Antwort zu
geben.
(Naja, nicht ganz. Ich hatte die Datenblätter schon auf der Platte)

Autor: Philipp Karbach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so hab jetzt ein bisschen weiter studiert und bin soweit gekommen:

#include <avr/io.h>
#include <avr/delay.h>

int DATA[] = { 0xFF, 0x3C, 0x00, 0xFF, 0x3C, 0x00, 0xFF, 0x3C,
        0x00, 0xFF, 0x3C, 0x00, 0xFF, 0x3C, 0x00, 0xFF};

int main ()
{
  DDRB=0xff;
  PORTB=0x00;
  int i=0;

  TCCR2 = (_BV(WGM21) | _BV(WGM20) | _BV(COM21) | _BV(COM20) |
_BV(CS20));
  while(1) {
    for (i=0;i<15;i++)
      OCR2=255-DATA[i];
  }

  return 0;
}

an PB.3 hab ich einen Piezo gehängt und der erzeugt einen sehr hohen
ton (ca. 1200Hz?). Nach meiner einstellung in TCCR2 sollte ich ja genau
den Takt der CPU Clock erzeugen oder? Welche Frequenz erzeuge ich denn
hier? (mein quartz hat 16.000Mhz). Ihr seht vielleicht, dass ich schon
irgendwelche daten ausgeben will! Mein Ziel ist es irgendwie eine Wave
datei mal abzuspielen ;). Dabei lese ich immer wieder dass man
"einfach" die daten am PWM ausgibt und dann mit der richtig frequenz
abspielt. Das muss ich aber erstmal richtig verstehen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Timer läuft einmal alle 256 Schritte über, also mit einer Frequenz
von 62,5 kHz. Das ist die Frequenz deiner PWM. Dein Programm rennt
allerdings arg schnell durch. Deine Schleife ändert den Wert für OCR2
so schnell sie kann, also ziemlich oft, bevor er überhaupt gebraucht
wird. Der Ton, den du hörst, ist möglicherweise irgenein
Interferenzmuster aus deiner PWM-Frequenz und der Frequenz, mit der du
OCR2 änderst. Du solltest vielleicht den OCR2-Wert besser im
Timer-Overflow-Interrupt ändern, damit er genau einmal pro
PWM-Durchlauf geändert wird.

Autor: Philipp Karbach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
stimmt daran hab ich noch gar nicht gedacht! ich hab das jetzt mal mit
dem interrupt versucht aber ich glaub das ist nicht so ganz richtig
oder? Welchen muss ich genau nehmen.

SIGNAL (SIG_OUTPUT_COMPARE2) {
  for (i=0;i<15;i++)
      OCR2=255-DATA[i];
}


int main ()
{
  DDRB=0xff;
  PORTB=0x00;

  TCCR2 = (_BV(WGM21) | _BV(WGM20) | _BV(COM21) | _BV(COM20) |
_BV(CS20));

  sei ();

  for(;;);

  return 0;
}

so bekomme ich gar keinen ton mehr.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Vektor ist der richtige, aber du schaltest nirgends den
Output-Compare-Interrupt ein.
Außerdem rennt die Schleife immer noch mit maximaler Geschwindigkeit
durch, aber halt nur noch einmal pro Timer-Durchlauf. Du darfst bei
jedem Interrupt nur einen Wert an OCR2 ausgeben.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach, moment. Du solltest nicht den output-compare-Interrupt nehmen,
sondern den für Overflow.

Autor: Philipp Karbach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so nächster tag ;),

ich hab das jetzt so aufgebaut:
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>

#define FREQ 440
#define TIMER 255 - (FREQ/128)

int DATA[] = { 0xFF, 0x3C, 0x00, 0xFF, 0x3C, 0x00, 0xFF, 0x3C,
        0x00, 0xFF, 0x3C, 0x00, 0xFF, 0x3C, 0x00, 0xFF};
        
int i=0;

SIGNAL (SIG_OVERFLOW2) {
  if(i>15)
    i=0;
    
  OCR2=255-DATA[i];
  i++;
  TCNT2 = TIMER;
}

int main ()
{
  DDRB=0xff;
  PORTB=0x00;
  
  TCCR2 = (_BV(WGM21) | _BV(WGM20) | _BV(COM21) | _BV(COM20) |
_BV(CS20));
  TIMSK |= (1 << TOIE2);
  TCNT2 = 0;
  
  sei ();
  
  for(;;) {
  }
  
  return 0;
}

aber der rennt durch den overflow interrupt durch. Was mach ich denn
noch falsch? Ich möchte meine daten mit einer genauen frequenz
abspielen. vielen dank für eure antworten!

Autor: Philipp Karbach (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ich hab das ganze jetzt wie im anhang zu sehen gelöst. Irgendwie find
ich das aber etwas seltsam. Mit TCNT2 bzw. OVERFLOW2 hab ich es nicht
hinbekommen. Ich denke jetzt ist es relativ genau oder?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab das Gefühl, daß du noch nicht ganz verstanden hast, wozu die PWM
da ist. Mir ist nicht klar, ob du die eigentlich überhaupt haben willst.
Warum verstellst du auf einmal TCNT1 in der Interrupt-Routine? Damit
verstellst du die PWM-Frequenz, statt nur die Pulsweite.
Also: Willst du nun einfach nur ein rechteckförmiges Signal mit
bestimmter Frequenz haben oder eine PWM, über die du die Wellenform
auch bestimmen kannst? Momentan macht dein Programm ein Mischmasch aus
beidem.

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.