Mega 2560, PWM mit variablem Puls/Pause Verhältnis erzeugen

Gast #6950260
Lesenswert?

Guten Morgen,

für eine Schrittmotor Endstufe möchte ich ein PWM Signal erzeugen.
Da ich noch viel ausprobieren und später darüber die Rampen erzeugen 
möchte, wäre eine schnelle Möglichkeit das Puls/Pause Verhältnis sowie 
die Periodendauer anzupassen hilfreich.

Dazu kam mir die Idee, das mit Hilfe von Timer1 im CTC Modus und der 
beiden Interrupts von COMP1A und COMP1B zu realisieren.

Wenn ich das Datenblatt richtig verstanden habe, setzt nur ein Compare 
Match von COMPA das Zählregister auf Null(mit OCR1A als TOP), die 
anderen OutputCompare Units lassen das Zählregister in Ruhe.

Dann gebe ich mit OCR1A die Periodendauer an und mit OCR1B die 
Pulslänge.

Der Ablauf sieht dann folgendermaßen aus:

- Bei Timerstart einmal den PWM Ausgang händisch auf 1 setzen
- der zuerst auftretende CompB Match bzw der Interrupt löscht nur den 
PWM Ausgang
- danach wird der TOP Wert erreicht und die ISR von CompA setzt den 
Ausgang wieder auf 1. TCNT1 wird automatisch auf 0 gesetzt.

Kann das theoretisch funktionieren? Die PWM Generierung funktioniert 
noch nicht richtig und bevor ich stundenlang einen Fehler im Code suche, 
wäre es hilfreich zu wissen ob das überhaupt funktionieren kann.

Danke im Vorraus

Andre
Gast #6950630
Lesenswert?

Hi,

Timer0 :
prescaler = 1 —> PWM frequency is 31000 Hz
prescaler = 2 —> PWM frequency is 4000 Hz
prescaler = 3 —> PWM frequency is 490 Hz (default value)
prescaler = 4 —> PWM frequency is 120 Hz
prescaler = 5 —> PWM frequency is 30 Hz
prescaler = 6 —> PWM frequency is <20 Hz

Timer1-4:
prescaler = 1 —> PWM frequency is 62000 Hz
prescaler = 2 —> PWM frequency is 7800 Hz
prescaler = 3 —> PWM frequency is 980 Hz (default value)
prescaler = 4 —> PWM frequency is 250 Hz
prescaler = 5 —> PWM frequency is 60 Hz
prescaler = 6 —> PWM frequency is <20 Hz

timer 0 controls pin 13, 4
timer 1 controls pin 12, 11
timer 2 controls pin 10, 9
timer 3 controls pin 5, 3, 2
timer 4 controls pin 8, 7, 6

nur noch den richtigen Timer wählen für die jeweiligen pins.
1
void update_base_pwm_freq(int p){
2

3
  switch (p){
4
    case 1:
5
      TCCR1B = TCCR1B & B11111000 | B00000101; // for PWM frequency of 30.64 Hz
6
    break;
7

8
    case 2:
9
      TCCR1B = TCCR1B & B11111000 | B00000100; // for PWM frequency of 122.55 Hz
10
    break;
11

12
    case 3:
13
      TCCR1B = TCCR1B & B11111000 | B00000011; // for PWM frequency of 490.20 Hz (The DEFAULT)
14
    break;
15

16
    case 4:
17
      TCCR1B = TCCR1B & B11111000 | B00000010; // for PWM frequency of 3921.16 Hz
18
    break;
19

20
    case 5:
21
      TCCR1B = TCCR1B & B11111000 | B00000001; // for PWM frequency of 31372.55 Hz
22
    break;
23

24
  }
25
}
#6950838
Lesenswert?

Hallo,

@ TO:
hast du einen Arduino Mega 2560 oder einen nackten ATmega2560?

Händisch irgendwelche Pegel schalten muss man nicht solange man den 
Timer zugehörigen Ausgangspin verwendet. Dann benötigt man auch keine 
ISR. Im nicht invertierenden Modus wechselt der Pegel automatisch auf 
High wenn der Counter seinen Wechsel/Reset auf Null erledigt. Der 
Counter läuft wieder hoch, erreicht irgendwann seinen Compare Match, 
schaltet den Pegel auf Low, Counter läuft weiter bis TOP, nullt sich und 
legt gleichzeitig den Pegel wieder auf High. Die Periode startet von 
vorn, wieder mit High- gefolgt von der Low Phase.
Gast #6950849
Lesenswert?

Andre schrieb:
> für eine Schrittmotor Endstufe möchte ich ein PWM Signal erzeugen.
> Da ich noch viel ausprobieren und später darüber die Rampen erzeugen
> möchte, wäre eine schnelle Möglichkeit das Puls/Pause Verhältnis sowie
> die Periodendauer anzupassen hilfreich.

Warum willst Du auf einen Schrittmotortreiber verzichten?
Dieser erledigt die Stromregelung am besten.
Gast #6951397
Lesenswert?

m.n. schrieb:
> Warum willst Du auf einen Schrittmotortreiber verzichten?
> Dieser erledigt die Stromregelung am besten.

Ich will nur die Schritte vorgeben, die der Motor fahren soll. Den 
Stromchopper erledigt die Endstufe.

Ich hab gestern mal die einzelnen PWM Module des 2560 studiert und die 
Fast PWM scheint das gesuchte zu sein. Ich glaub die meinte Veit auch, 
oder?

Denn die anderen erzeugen den Impuls in der Mitte der Periode, das kann 
ich nicht gebrauchen. Ich brauche am Anfang einen 5-10 µs Impuls ud dann 
die Pause. Zuimindest während der Start und Stoprampe.

@Veit

Genau das wollte ich erreichen. Das über die Fast PWM zu machen hat den 
Vorteil, ich spare mir einen ISR vom COMPB. Den anderen brauche ich, um 
die Rampe vorzugeben und die Schritte mitzuloggen.
Das werde ich nachher mal testen.

Ist ein Arduino Mega 2560.

Danke euch für die Hilfe

Andre
#6951724
Lesenswert?

Hallo,

das war die allgemeine Beschreibung wie PWM erzeugt wird. Den Fast-PWM 
Modus würde ich beim ATmega nicht verwenden wenn es nicht unbedingt sein 
muss, bspw. weil man einen hohen Takt benötigt. Ansonsten erstmal alle 
anderen außer Fast-PWM. Warum? Fast-PWM erzeugt mit Compare Match 0 
einen Nadelimpuls. Man hat damit keinen 100,000% Low Pegel. Kann man mit 
einer Led testen, 100Hz und Pulsweite 0. Phase/Frequency Correct Mode 
haben das Problem nicht. Sie erzeugen den Puls etwas anders, was dich 
aber nicht aus der Ruhe bringen sollte. Das spielt nach außen keine 
Rolle und hat nur Vorteile.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren