Forum: Mikrocontroller und Digitale Elektronik 16 bit Software PWM mit ATMEGA


von soulid (Gast)


Lesenswert?

Hallo,
ich möchte gerne einen ATMEGA1250 (auf einem Arduino MEGA Board) ein PWM 
per software aufbauen. Das auf dem Board bestehende 8Bit PWM reicht mir 
nicht aus- es sollten schon 10 oder 12 Bit sein.
Folgenden Code habe ich geschrieben:

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

void setup() {
  // initialize the digital pin as an output.
  DDRB= B11111111; // set PORTB (digital 13-8) to outputs
  cli();          // disable global interrupts
  TCCR1A = 0;     // set entire TCCR1A register to 0
  TCCR1B = 0;     // same for TCCR1B
  TCCR1B |= (1 << CS10);  // Set CS10  bit only for prescaler 1
  sei(); // enable global interrupts:
}


void loop() {


  if (TCNT1 < 5){
    PORTB=B10000000;
  }


  if (TCNT1 > 20000){
    PORTB=B00000000;
  }
}


Leider bekomme ich ein ziemlich unregelmässiges PWM welches deutlich 
sichtbar (mal mehr- mal weniger) flackert, aber auch für kurze Zeit ein 
unsichtbares PWM generiert. Es ist keinesfalls ein regelmässiges 
Verhalten.

Kann mir jemand helfen? Bin ich mit der Timeridee vielleicht auf völlig 
auf dem Holzweg?

von Falk B. (falk)


Lesenswert?

@  soulid (Gast)

>per software aufbauen. Das auf dem Board bestehende 8Bit PWM reicht mir
>nicht aus- es sollten schon 10 oder 12 Bit sein.

Warum dann 16 Bit in der Betreffzeile?

>Folgenden Code habe ich geschrieben:

Naja.

>Leider bekomme ich ein ziemlich unregelmässiges PWM welches deutlich
>sichtbar (mal mehr- mal weniger) flackert, aber auch für kurze Zeit ein
>unsichtbares PWM generiert. Es ist keinesfalls ein regelmässiges
>Verhalten.

Schon mal drüber nachgedacht, wie dein Timing sicher und solide 
funktionieren soll? Wieviel Takte der Prozesoor zwischen zwei PWM-Takten 
hat?

>Kann mir jemand helfen? Bin ich mit der Timeridee vielleicht auf völlig
>auf dem Holzweg?

Timer ist schon richtg, aber nicht so, das ist vollkommen daneben. Wie 
man es richtig macht steht im Artikel Soft-PWM.

von Karl H. (kbuchegg)


Lesenswert?

soulid schrieb:

> Kann mir jemand helfen? Bin ich mit der Timeridee vielleicht auf völlig
> auf dem Holzweg?

Im Prinzip nicht, aber so wie du das zu realisieren versucht schon.

Deine PWM ist darauf angewiesen, dass loop() oft genug aufgerufen wird, 
dass du so wenige Timerticks wie möglich verpasst. Und die Arduino 
Lufzeitumgebung scheint das nicht mehr gewährleisten zu können.

Timer ist gut. Besorg dir das Datenblatt zu deinem µC und studier die 
entsprechenden Abschnitte darin zum Thema Timer 1. Dein Timer kann 
nämlich auch ganz alleine eine PWM in Hardware erzeugen.

von soulid (Gast)


Lesenswert?

Hallo Karl- Heinz,
danke für die freundliche Antwort. Ich verstehe jetzt das der ATMEGA328 
mit dem Prescaler 1 zu langsam sein musste. Ich habe zwischenzeitlich 
den Code so verändert das ich keinen HIGH Zyklus verpasse (denn das war 
passiert).

Also if (TCNT1 < 5) zu
if (TCNT1 < 50)

und das Ergebnis war ein regelmässiges leuchten (aber die PWM Regelung 
natürlich vieel zu unpräzise). Ich schau mir jetzt mal den Arduino Due 
an. Vielleicht hat der ja einen 16 Bit Timer der (durch die höhrere 
Taktfrequenz von 84MhZ) mit eine anderen Prescaler betrieben werden 
kann. Dann hat der Code mehr Zeit zur Ausführung und vermeidet damit die 
Unregelmässigkeiten.

Danke nochmal

von Falk B. (falk)


Lesenswert?

@  soulid (Gast)

>danke für die freundliche Antwort. Ich verstehe jetzt das der ATMEGA328
>mit dem Prescaler 1 zu langsam sein musste.

Richtig.

> Ich habe zwischenzeitlich
>den Code so verändert das ich keinen HIGH Zyklus verpasse (denn das war
>passiert).

Nö, du hast nichts kapiert. 16 Bit PWM geht nur in Hardware, weil der 
PWM-Takt dann gleich CPU-Takt ist (Prescaler 1).

>an. Vielleicht hat der ja einen 16 Bit Timer der (durch die höhrere
>Taktfrequenz von 84MhZ)

84 MHz beim ATmega? Hab ich was verpasst?

von Purzel H. (hacky)


Lesenswert?

Man kann ein 16 bit PWM auch mit der Hardware machen. Die ersten 8 bit 
per 8Bit PWM. Mit einem 16MHz Quarz liegt man dann bei 64kHz. Die 
naechsten 8 Bit macht man per Dithering, Dh, anstelle den ersten Zaehler 
mit zB 82 laufen lassen, schaltet man zB 64 mal 82 und 192 mal 83 auf 
den Zaehler.
Die Periode kommt dann auf 256 Hz runter, obwohl die PWM mit 64kHz 
laeuft.

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.