mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik pwm atmega16 falsche frequenz


Autor: Stefan Z. (derdespot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo leute, ich versuche grade eine pwm mit dem atmega16 zu erzeugen 
und kriege komischerweise eine frequenz von 15,63khz anstatt wie 
eingestellt 20khz. hat jemand ne idee weshalb das so ist?

#define TIMER_MAX 200

void pwm(void){

TCCR2 = 0b01101001;
TCNT2 = TIMER_MAX;

// FOC | WGM20 | COM21 | COM20 | WGM21 | CS22 | CS21 | CS20
// Fast PWM | non-inverting mode | No prescaling
// f_PWM = f_CLK / N * TCNT2 | f_CLK = 4MHz | N = 1 | TCNT2 = 200 | ==> 
20kHz

OCR2 = (0.50 * TIMER_MAX);
ASSR |= (0<<AS2); // synchronous timer/counter2
}

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

Bewertung
0 lesenswert
nicht lesenswert
Wie kommst du auf die 20kHz?

(Die Zahl ist mir etwas zu glatt. Da musst du einen sehr krumme 
Taktfrequenz haben, damit sich 20kHz einstellen)


#define TIMER_MAX 200
TCNT2 = TIMER_MAX;
Ähm. Du denkst jetzt aber nicht wirklich, dass du den Zählbereich des 
Timers auf die Art auf 0 bis 200 limitiert hast? Zumindest der Kommentar
// f_PWM = f_CLK / N * TCNT2 | f_CLK = 4MHz | N = 1 | TCNT2 = 200 | ==> 20kHz

lässt in mir diesen Verdacht aufkommen.


Edit:
TCCR2 = 0b01101001;

Wenn man nur diesen Unsinn ausrotten könnte. Ich brauch fast 2 Minuten 
um durch Vergleich mit dem Datenblatt + Notizzettel zu erkennen, welche 
Bits da gesetzt sind. (Wenn ich im Datenblatt endlich die Tabelle 
erscrollt habe um die gesetzten Bits mit einem Modus in Verbindung zu 
bringen, hab ich schon wieder vergessen, welcher 1-er denn nun welches 
Bit war. Also wieder zurückscrollen und mit der Register-Bit 
Beschreibung vergleichen. Mist, jetzt hab ich die Bits wieder den 
Bitnamen zugeordnet, aber wie war das nochmal in der Tabelle? und schon 
wieder scrollen ....
  TCCR2 = ( 1 << WGM20 ) |
          ( 1 << WGM21 ) |
          ( 1 << COM21 ) |
          ( 1 << CS20  );

Autor: Stefan Z. (derdespot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie define legt doch 200 fest oder?

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

Bewertung
0 lesenswert
nicht lesenswert
Stefan Z. schrieb:
> wie define legt doch 200 fest oder?

Ja und?

Definieren kann ich viel.
Aber deiner Hardware ist das ziemlich egal, was du definierst.

Datenblatt Mega16, Tabelle 17-2
Fast-PWM Mode, der Timer zählt von 0 bis 0xFF

4Mhz / 256 = 15.6 kHz

Passt auffallend

Autor: Stefan Z. (derdespot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ahh ok danke, ich dachte die 256 im datenblatt stehen für das TCNT2 
register, welches beliebig beschrieben werden kann. nun ist halt die 
frage wie ich genau 20khz hinbekomme? wahrscheinlich nur mit einem 10bit 
timer

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

Bewertung
0 lesenswert
nicht lesenswert
Stefan Z. schrieb:
> ahh ok danke, ich dachte die 256 im datenblatt stehen für das TCNT2
> register, welches beliebig beschrieben werden kann. nun ist halt die
> frage wie ich genau 20khz hinbekomme? wahrscheinlich nur mit einem 10bit
> timer

Such dir im Datenblatt den Timer, bei dem du die Obergrenze festlegen 
kannst ( in den PWM Tabellen ist das der TOP Wert )

Autor: Stefan Z. (derdespot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, danke

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Such dir im Datenblatt den Timer, bei dem du die Obergrenze festlegen
>kannst ( in den PWM Tabellen, ist das der TOP Wert )

Oder nimm einen passenden Quarz. 5,12MHz (Reichelt) passt genau.

MfG Spess

Autor: Stefan Z. (derdespot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void pwm(void){
  TCCR1A |= (1<<COM1A1); // fast pwm , non-inverting mode)
  TCCR1A |= (1<<COM1B1); // fast pwm , non-inverting mode)
  TCCR1A |= (0<<COM1A0); // fast pwm , non-inverting mode)
  TCCR1A |= (0<<COM1B0); // fast pwm , non-inverting mode)
  TCCR1A |= (1<<WGM11); // Fast PWM, 10-bit
  TCCR1A |= (1<<WGM10); // Fast PWM, 10-bit
  TCCR1B |= (1<<WGM12); // Fast PWM, 10-bit
  TCCR1B |= (0<<WGM13); // Fast PWM, 10-bit
  TCCR1B |= (0<<CS12); // clkI/O/1 (No prescaling)
  TCCR1B |= (0<<CS11); // clkI/O/1 (No prescaling)
  TCCR1B |= (1<<CS10); // clkI/O/1 (No prescaling)

  TCNT1H = 0x00;
  TCNT1L = 0xC7; // 199 + 1 ==> 4MHz / 1 * (1 + 199) ==> 20kHz

  OCR1AH = 0x00;
  OCR1AL = 0xA0;
  OCR1BH = 0x00;
  OCR1BL = 0xA0;
}

Ich messe 3,9 kHz. So ein Mist...

Autor: Chridre (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da du mit einem PWM-Signal arbeitest darfst du nicht verwechseln, dass 
du hier die Einschaltlänge einstellst und nicht die häufigkeit wie oft 
An- und Ausgeschlatet wird.
Musste auch mal eine Frequenz von 40 kHz erzeugen ich habe dies dann 
über den Compare Output Mode and Waveform Generation gemacht.
Im Datenblatt vom Atmel ist da auch eine Formel zufinden mit der man 
sich die Frequenz errechnen kann und dann dementsprechend die Werte dazu 
einstellt.
Ich hoffe ich könnte dir damit helfen.

Grüße

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

Bewertung
0 lesenswert
nicht lesenswert
TCCR1A |= (1<<WGM11); // Fast PWM, 10-bit
  TCCR1A |= (1<<WGM10); // Fast PWM, 10-bit
  TCCR1B |= (1<<WGM12); // Fast PWM, 10-bit
  TCCR1B |= (0<<WGM13); // Fast PWM, 10-bit


Was ist daran so schwer zu verstehen, dass du in der Tabelle der PWM 
Modi einen Modus brauchst, bei dem der TOP Wert keine Konstante ist, 
sondern über ein Register festgelegt werden kann.

Du hast hier einen Fast-PWM MOdus mit 10 Bit eingestellt und laut 
Datenblatt ist der TOP Wert dafür 0x03FF, also dezimal 1023

4000000 / 1023 = 3910 Hz

Passt schon wieder auffallend.

(PS: Lass das TCNT Register in Ruhe. Darin zählt der Timer. Aber 
logischerweise kann das nicht die Steuerung dafür sein, wann der Timer 
auf 0 zurückgesetzt wird)

Tabelle 16-5
Modus 14 oder Modus 15 würden dir erlauben in ICR1 bzw. OCR1A 
festzulegen, wie weit der Timer (im Register TCNT1) zählen soll, ehe er 
wieder bei 0 beginnt.

Autor: Stefan Z. (derdespot)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jetzt gehts, super danke!!!

void pwm(void){
  TCCR1A |= (1<<COM1A1); // Clear OC1A/OC1B on compare match when 
up-counting
  TCCR1A |= (1<<COM1B1); // Clear OC1A/OC1B on compare match when 
up-counting
  TCCR1A |= (0<<COM1A0); // Clear OC1A/OC1B on compare match when 
up-counting
  TCCR1A |= (0<<COM1B0); // Clear OC1A/OC1B on compare match when 
up-counting
  TCCR1A |= (0<<WGM11); // Phase and Frequency Correct PWM Mode
  TCCR1A |= (0<<WGM10); // Phase and Frequency Correct PWM Mode
  TCCR1B |= (0<<WGM12); // Phase and Frequency Correct PWM Mode
  TCCR1B |= (1<<WGM13); // Phase and Frequency Correct PWM Mode
  TCCR1B |= (0<<CS12); // clkI/O/1 (No prescaling)
  TCCR1B |= (0<<CS11); // clkI/O/1 (No prescaling)
  TCCR1B |= (1<<CS10); // clkI/O/1 (No prescaling)

  ICR1 = 0x64; // 4MHz / 2  1  100) ==> 20kHz

  OCR1AH = 0x00;
  OCR1AL = 0x43; // duty cycle
}

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.