Forum: Mikrocontroller und Digitale Elektronik Mega 2560, PWM mit variablem Puls/Pause Verhältnis erzeugen


von Andre (Gast)


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

von Sebastian R. (sebastian_r569)


Lesenswert?

Der Timer hat doch einen PWM-Modus, der komplett ohne Interrupts 
auskommt.

von hmm (Gast)


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
}

von Veit D. (devil-elec)


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.

von m.n. (Gast)


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.

von Andre (Gast)


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

von Veit D. (devil-elec)


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.

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.