Guten Abend,
ich möchte mit einem MSP430g2453 zwei TimerA testweise zur Erzeugung von
2 PWMs erzeugen jedoch verwirren mich gerade der User Guide von TI und
diverse Beispiele im Internet.
Mein Ansatz:
Ich habe einen TimerA0 und TimerA1, die ich jeweils mit Der Taktquelle
verbinde, ihnen den Modus zuteile und eventuell, wenn gewünscht einen
Teiler zuweise. Weiterhin muss ich die Interrupts Aktivieren und die
CCRx Werte zuweisen. Jetzt ist mein Problem, dass ich nicht ganz
verstehe, welches der Interrupts wozu gehört.
Welches Interrupt wird bei TAxCTL (TAIE) ausgelöst und welches mit dem
CCIE? Oder ist dort etwas doppelt(zuviel), wenn ich Globale Interrupts
erlaube.
Soweit ich weiss, gibt es einmal die verwendeten, TIMERA0_A1_VECTOR und
TIMERA1_A1_VECTOR, Vectoren und auch TIMERA0_A0_VECTOR bzw
TIMERA1_A0_VECTOR.
Da bin ich gerade etwas durcheinander.
Vielleicht kann mir ja jemand weiterhelfen.
Danke im Vorraus!!
Code:
Hallo,
ja klar, für die PWM müsste ich diese noch zuweisen, aber die Variablen
waren jetzt auch nur für einen Test, um zu sehen, in welche er
reinspringt.
Funktioniert leider immer noch nicht so, wie es soll.
Verstehe da glaube ich irgendwas falsch.
Helfen tut alles!!
Danke schonmal,
Das Problem bei mir ist leider, die Timer anders angesprochen werden.
Soweit ich jetzt nochmal probiert habe, muss ich wohl zB.
für TimerA0:
1
TA0CTL|=TAIE;
für TimerA1:
1
TA1CTL|=TAIE;
initialisieren, um die Interrupts für den Überlauf zu aktivieren, statt
die im gleichen Atemzug wie
1
TA0CTL=TASSEL_2+TAIE;
Habe hier im Forum noch etwas gefunden, welche Interrupts bei Überlauf,
CCR0, CCR1 und CCR2 aufgerufen werden.
Ist es also richtig, dass Überlauf bzw. CCR0
1
TIMER0_A0_VECTOR
bzw.
1
TIMER1_A0_VECTOR
und CCR1 & CCR2
1
TIMER0_A1_VECTOR
bzw.
1
TIMER1_A1_VECTOR
aufrufen?
Wenn das richtig ist, muss ich eigentlich nur noch genau wissen welche
TAIV Bits ausgelesen werden müssen.
Bei TIMER0_A1_VECTOR sollte es doch TA0IV sein und
bei TIMER1_A1_VECTOR sollte es doch TA1IV sein.
Zu deinem Code, Danke, das mit der Funktion
Stefan S. schrieb:> void Start_Timer_A(int adc_wert)
war echt Hilfreich!!
Nur die erste Funktion verstehe ich nicht ganz. Ist es sinnvoller so
etwas in Funktionen zu initialisieren oder in der Main?
Also um hier mal ein bisschen Klarheit reinzubringen:
Dein Prozessor hat zwei Timer (TA0 unf TA1) mit je drei Zählregistern
(CCR0, CCR1 und CCR2). Diese beiden Timer sind individuell voneinander
konfigurierbar.
Zum TA0 gehören folgende Interrupt-Handler:
TIMER0_A0_VECTOR und TIMER0_A1_VECTOR
Der erste ist ausschließlich für CCR0, der zweite bedient CCR1, CCR2 und
den Überlauf, weche mittels TA0IV ausgewertet werden können, dabei gilt:
2: CCR1
4: CCR2
10: Überlauf
Genauso ist es für den Timer 1, nur eben mit seinen eigenen Registern,
welche sich aber nur mit der 0 und der 1 in ihrem Namen unterscheiden.
Jetzt mal zu deinem Code:
E. Isser schrieb:> TA0CTL = TASSEL_2 + TAIE;
Hier sagst du, dass Timer 0 als Quelle SMCLK bekommt und dass der
ÜBERLAUF einen Interrupt auslösen soll - mehr erstmal nicht.
E. Isser schrieb:> TA0CCR0 |= 65535-1;
CCR0 hält den Wert, bei dem der Timer einen Interrupt auslösen könnte,
wenn du ihn in dem Modus betreibst - ein Wert von 65534 ist natürlich
totaler Quatsch, denn da kannste auch einfach nur den Überlauf nehmen,
was du ja auch schon getan hast. Außerdem verodert man den Wert nicht
mit dem Register, da dan definitiv nicht die Zahl drin steht, die man
wollte.
E. Isser schrieb:> TA0CCR1 |= 32000 + CCIE;
Das ist jetzt leider totaler Blödsinn, denn auch CCR1 ist ein Register
zum Halten eines Wertes - du kannst hier kein Bit für den Capture
Compare Interrupt setzen. Das setzt du in TA0CCTL1 (hier in deinem Fall
für TA0.1) - dann würde der Timer beim Erreichen des Wertes in TA0CCR1
einen Interrupt auslösen.
E. Isser schrieb:> TA0CTL = MC_1;
Hier kommt leider ein weiterer großer Fehler, denn du überschreibst beim
Setzen des Modus auf Up mit dem "=" alle Einstellungen, die du vorher in
TA0CTL gemacht hast, also die Taktquelle und das TAIE. Hier gehört die
Veroderung hin.
Wenn du deine PWM unbedingt in Software lösen willst, dann würde ich es
folgendermaßen machen:
Mit einem Timer setzt du die Perdiodendauer, also setzt du z.B. TA0CCR1
auf 50000. Mit einem zweiten Timer TACCR2 setzt du das Tastverhältnis -
hier trägst du z.B. einen Wert von 25000 ein, wodurch du eine PWM mit
50% Duty-Cycle bekommst. Verändern tust du nur CCR2. Das ganze im
Up-Mode.
In den ISRs passiert folgendes:
CCR1: Ausgangspin auf high
CCR2: Ausgangspin auf low
Fertig ist die PWM.
Aber es wäre blöd, das in Software zu lösen, wenn der MSP das auch in
Hardware kann.
Stefan S. schrieb:> void Init_Timer_A(void) // Timer A init> {> TACTL = TASSEL_2 + ID_0 + MC_1;> }>>> void Start_Timer_A(int adc_wert)> {> TACCTL1 = OUTMOD_7;> TACCR0 = 1024;> TACCR1 = adc_wert;> }
Und das ist genau die richtige Variante dafür. CCR0 setzt den Pin auf
high, CCR1 auf low und das ohne ISRs, welche man dann natürlich auch
nicht braucht - eine leere ISR wie diese hier
Stefan S. schrieb:> #pragma vector = TIMERA0_VECTOR> __interrupt void TimerA_ISR(void)> {>> }
lässt man dann weg, ABER setzt auch kein CCIE- oder TAIE-Bit, denn kann
der uC sich irgendwo verrennen.
So, hoffe, es ist ein bisschen klarer. Gruß,
Dennis
Nachtrag:
Dennis schrieb:> Außerdem verodert man den Wert nicht> mit dem Register, da dan definitiv nicht die Zahl drin steht, die man> wollte.
Beim Start kann es OK sein, wenn das Register mit 0 initialisiert wird.
Trotzdem: Lass es da gehört ein "=" oder ein "+" hin, letzteres aber
eher im Cont-mode.
Sorry, noch ein Fehler entdeckt:
Dennis schrieb:> In den ISRs passiert folgendes:> CCR1: Ausgangspin auf high> CCR2: Ausgangspin auf low
Das muss heißen:
CCR0: Ausgangspin auf high
CCR1: Ausgangspin auf low
Dennis schrieb:> So, hoffe, es ist ein bisschen klarer. Gruß,
Das hat mir sogar sehr geholfen. Vielen Dank für die Mühe!!
Dennis schrieb:> denn du überschreibst beim> Setzen des Modus auf Up mit dem "=" alle Einstellungen,
Das war denke ich auch eines der Dinge die ich jetzt verstanden habe.
Dennis schrieb:> Hier gehört die Veroderung hin.
Ich glaube ich hatte das auch nicht ganz verstanden, dass man Bits mit
|= setzt und quasi Einstellungen mit einem = festlegt.
Dennis schrieb:> Wenn du deine PWM unbedingt in Software lösen willst
Das war ja nur für einen Test, natürlich muss ich die Direction und
Selection noch auf die entsprechenden Ausgägne setzen.
Ich glaube das hat mir sehr weitergeholfen. Werde es mal probieren.
Vielen Dank!
E. Isser schrieb:> Ich glaube das hat mir sehr weitergeholfen. Werde es mal probieren.> Vielen Dank!
Kein Problem, gerne. Habe übrigens nochwas in meinem Text gefunden
Dennis schrieb:> Lass es da gehört ein "=" oder ein "+" hin, letzteres aber> eher im Cont-mode.
Und da muss es natürlich "+=" heißen, nicht nur "+". Sorry
Also ich habe es heute mal ausprobiert und siehe da, es läuft!!
Allerdings habe ich ein kleines Problem und weiss da nun absolut nicht
was das sein kann.
Die 2 PWMs werden erzeugt und laufen auch bei verschiedenen Werten
super. Zwischendurch tritt aber für einen winzigen Augenblick ein Fehler
auf, bzw die LEDs, welche ich angeschlossen habe leuchten kurz ganz hell
auf, oder sind kurz dunkel. Das Ganze ist in einem Bruchteil einer
Sekunde. Was kann das denn sein?