Hallo zusammen.
Ich lerne momentan für meine kommende Embedded Systems Klausur und
wollte, bevor ich zu den schweren Aufgaben komme, nochmal die leichten
Aufgaben durchgehen.
Da ich eh noch Probleme mit dem ADC und PWMs habe, hab ich mir bevorzugt
diese Aufgaben angeguckt.
Leider funktioniert eine Aufgabe nicht mehr richtig und ich habe keine
Ahnung warum, da eine andere Aufgabe mit einem ähnlichen Aufbau
einwandfrei funktioniert...
Deswegen hoffe ich das mir hier einer weiterhelfen kann.
Ich benutze ein MSP430G2553 (mit der IAR Workbench).
Die Aufgabe ist relativ simpel...man soll die grüne LED des Pads
mithilfe einer PWM dimmen.
Hier mal mein Quellcode dafür:
1
#include"msp430.h"
2
3
//PWM
4
5
#define LED_G BIT6
6
7
intmain(void)
8
{
9
// Stop watchdog timer to prevent time out reset
10
WDTCTL=WDTPW+WDTHOLD;
11
12
//Als Ausgang definieren
13
P1DIR|=LED_G;
14
P1SEL|=LED_G;
15
16
17
TACTL=TASSEL_2+MC_3;//Einstellung Timerregister mit Takt SMCLK im Upmode
18
19
TACCR0=1000;
20
TACCR1=9;
21
22
TACCTL1=OUTMOD_3;// Outmode 3 = Set/Reset
23
24
while(1){}
25
26
}
Probleme:
1. Outmode 3 (Set/Reset) funktioniert nicht richtig.
Die LED is bei allen CCR1 werten gleich hell.
2. Outmode 7 (Reset/Set) funktioniert, allerdings falschrum.
Und zwar ist die LED bei niedrigen CCR1 Werten hell und bei hohen CCR1
Werten dunkel.
Ein Blick auf das Diagramm und die Tabelle zeigt aber (zumindest nach
meinem Verständnis)das bei CCR1 der Reset stattfindet und ab CCR0 wieder
gesetzt wird.
Ergo je größer der CCR1 wert umso kleiner der Resetzyklus umso heller
müsste die LED leuchten oder sehe ich was falsch?
Zum Vergleich ein Quellcode für eine Aufgabe bei der die LED automatisch
heller und wieder dunkler wird:
1
#include"msp430.h"
2
3
// Automatisches Dimmen
4
5
#define LED_G BIT6
6
7
voidmain(void)
8
{
9
WDTCTL=WDTPW+WDTHOLD;// Stop WDT
10
11
unsignedintii,aa;
12
13
P1DIR|=LED_G;// Pin von grüner LED als Ausgang
14
15
// Sekundäre Funktion aktivieren, hier Timerausgang => TA0.1
16
P1SEL|=LED_G;
17
18
TACCR0=1023;// Endwert
19
20
// Out-Modus auf Modus 7 stellen (R/S)
21
TACCTL1=OUTMOD0+OUTMOD1+OUTMOD2;
22
23
TACTL=TASSEL1+MC0;// Taktquelle, Zählmodus
24
25
// Eigentliches Programm
26
aa=0;
27
while(1)// Endlosschleife
28
{
29
for(ii=0;ii<1500;ii++);// Warteschleife
30
aa++;// Zählervariable erhöhen
31
32
if(aa==1023)// Wenn aa == 1023 => OUT-Modus ändern
33
{
34
aa=0;// aa zurücksetzen
35
TACCTL1^=OUTMOD2;// wechsel zwischen Mode 7 und Mode 3
36
}
37
TACCR1=aa;// TACCR1-Wert auf aa setzen
38
}
39
}
Hier startet die PWM im Outmode 7 und die LED wird mit steigendem CCR1
auch heller (wie auch in Diagramm & Tabelle geschildert).
Und nach dem toggeln in Outmode 3 (Set/Reset) wird die LED mit
steigendem CCR1 dunkler.
Jetzt ist natürlich meine Frage wieso es alles beim auto dimmen
funktioniert und in der simpleren Version nur halb und die Hälfte
nichtmal richtig?
Ich wäre wirklich sehr dankbar wenn mir da jemand Licht ins dunkel
bringen könnte ich bin da noch nicht so Fit mit dem Thema.
Vielen Dank für die Aufmerksamkeit,
mfg Bobba
Hallo und Danke für die Antwort.
So ähnlich mach ich es ja beim 2. Code und es funktioniert auch alles
wie es soll.
Allerdings funktioniert der 1. Code nicht wie er soll.
1
TACCTL1=OUTMOD_7;
entspricht
1
TACCTL1=OUTMOD0+OUTMOD1+OUTMOD2;
Nur funktioniert es im Modus 7 genau andersherum als im 2. Code und im
Modus 3 überhaupt nicht.
So liefert:
1
TACTL=TASSEL_2+MC_3;//Einstellung Timerregister mit Takt SMCLK im Upmode
2
3
TACCR0=1000;
4
TACCR1=10;
5
6
TACCTL1=OUTMOD0+OUTMOD1+OUTMOD2;
eine hell leuchtende LED und ein TACCR1 von 900 eine stark gedimmte
(obwohl es doch umgekehrt sein sollte oder nicht?).
Und im Modus 3 kann ich TACCR1 ändern wie ich will, die LED ist immer
gleich hell.
Ich weiß leider nicht wieso das im einem Code wie auch dem
Impulsdiagramm zu entnehmen funktioniert und im anderen nicht :/
Danke vorab für weitere Hilfe.
mfg Bobba
Florian N. schrieb:> so ähnlich mach ich es ja
aber nicht gleich ;-D
Mit welcher Taktquelle verbindest du den Timer?
In welchem Modus läuft der Timer?
Deine Konfiguration:
TACTL = TASSEL_2 + MC_3;
Meine Konfiguration:
TACTL = TASSEL1 | MC0 | TACLR;
Stell doch mein Beispiel einfach einmal auf OUTMODE 3 um.
Der Fehler im ersten Quellcode liegt am MC_3, der für den Up/Down-Mode
steht. Ändere dies in MC_1 für den Up-Mode. Folgendes ist dem MSP430
User Guide, unter dem Kapitel Timer A, entnommen:
MCx Mode Description:
00 Stop The timer is halted.
01 Up The timer repeatedly counts from zero to the value of TACCR0.
10 Continuous The timer repeatedly counts from zero to 0FFFFh.
11 Up/down The timer repeatedly counts from zero up to the value of
TACCR0 and back down to zero.
Der von dir gewählte (TASSEL_2) entspricht dem Takt des interen
Taktgebers SMCLK von 1,1MHz. Entspricht einer Zeit von ca. 1µs pro
Zähltakt. Das ergibt hinsichtlich deines Codes:
TACCR0 = 1000; // ca. 1ms
TACCR1 = 9; // ca. 9µs AUS 991 µs AN
Die LED sollte bei einem Wert von TACCR1 = 9950 stark gedimmt sein.
Wenn ich raten müsste, würde ich sagen, das riecht nach einer Klausur
von Herr Prof. K. vom Campus GM der FH K..
Tipp an alle MSP Anfänger,
"Trollmodus an"
Kuckt euch erst die Errata Files an!
"Trollmodus aus"
Zitat:"Das ist wirklich so, ling ling und bauer".
Im Ernst, vieles wird im Datenblatt beschrieben und in Wirklichkeit geht
es nur mit "Workaround". -> Z.B. Interuptmode bei I2C fail -> 430F2618T.
Gruß.
"Jetzt aber Trollmodus wirklich aus"
Danke für die Antworten :)
Leroy schrieb:> Der Fehler im ersten Quellcode liegt am MC_3, der für den Up/Down-Mode> steht.
Es sind immer diese Kleinigkeiten (und ich sitz da so lange dran und
weiß nit woran es liegt)....
Aber ok vielen Dank^^. (auch an MSP430)
Leroy schrieb:> Wenn ich raten müsste, würde ich sagen, das riecht nach einer Klausur> von Herr Prof. K. vom Campus GM der FH K..
Keine Klausur sondern normale Aufgaben :P (Klausur dürfte um einiges
schwerer werden)
Aber ja, macht man sowas an anderen Schulen nicht?(Oder woher kommt die
direkte Vermutung).
Hätte mittlerweile aber auch noch eine Frage:
Wenn ich eine PWM auslesen und auf meinem Launchpad wiedergeben möchte,
muss ich da den Timer_B mitbenutzen?
Fürs auslesen der PWM brauch ich ja schon 1 Timerregister im Capture
Mode.
Dann bräuchte ich ja noch einen für meine eigene PWM und der
TACCTL0-Register fällt ja weg da der CCR0-Wert als Vergleichswert für
die PWM genommen wird (zumindest im Up-mode).
Laut Userguide hätte mein Launchpad auchnoch einen 3. Timerregister
(Register 2).
Allerdings finde ich in den Pin-Belegungen keinen mit Sonderfunktion
(Timer-Ausgang) für diesen Register...
Dann war meine nächste Idee die PWM mithilfe des Continious-Mode zu
machen.
Das also ein Ereignis bei einem Zählerstand (z.B. CCR1) und 0xFFFFh
ausgelöst wird.
Aber leider würde, laut Impulsdiagram, mit CCR0 & CCR1 gearbeitet werden
und bei 0xFFFFh nichts passieren.
Jetzt ist die Frage ob ich den Timer_B genau wie den Timer_A benutzen
kann?
Und/Oder ob der CCR1 Zählregister, wenn ich den CCTL1-Register im
Capture-Mode betreibe, für die Compare-Funktionen ausgeblendet wird (er
im Up-mode also kein Ereignis auslösen würde)?
(eine Aufgabe aus dem Tutorium falls die Frage aufkommt)
Wäre auch hier nocheinmal dankbar für Hilfe.
mfg Bobba
F. N. schrieb:> Aber ja, macht man sowas an anderen Schulen nicht?(Oder woher kommt die> direkte Vermutung).
Vermutlich wird dies auch an anderen Hochschulen zum Einsatz kommen, nur
die Aufgabenstellung, sowie die Lösung des 2. Quellcode kam mir sehr
vertraut vor, obwohl es schon paar Jährchen zurück liegt. ;)
Selber bin ich nicht mehr ganz fit, was den MSP430 angeht aber zu deiner
Problematik des PWM auslesen würde ich folgende Betrachtung machen.
PWM = zyklisches EIN/AUS-Schalten,somit würde ich versuchen mittels
Interrupt über die Flankenerkennung an einem der Pins die EIN- und
AUS-Zeit zu ermitteln, um diese dann mit dem Timer A nachzubilden, indem
du die Werte in den TACCR0 und TACCR1 schreibst.
Beispiel Pin-Config:
Steigende Flanke
P1IES &= ~BIT 3;
Fallende Flanke
P1IES |= BIT3;
Ob du das auslesen der anliegenden PWM kontinuierlich betreibst, nach
einer Zeit t neu einliest oder das neu Einlesen per Taster auslöst,
überlasse ich deiner Fantasie.
Danke nochmals für die Antwort :)
Leroy schrieb:> die Lösung des 2. Quellcode kam mir sehr> vertraut vor
Obwohl das in Eigenarbeit mit ein bissle Tutoriumshilfe entstanden ist
:O
Hab jetzt selber noch ein wenig rumprobiert.
Wie ich die PWM auslese ist mir relativ klar.
Ich nehm nen Capture auf ne steigende Flanke, die folgende fallende und
wieder die steigende und kann das ganze dann ins Verhältnis setzen.
Das ganze braucht ja an sich auch nur 1 Timerregister.
Wenn ich aber jetzt gleichzeitig auch eine PWM rausgeben will bräuchte
ich allerdings ebenfalls 2 Timerregister (zumindest im Up-Mode).
Durch probieren hab ich jetzt rausgefunden das es anscheinend mit 1
Register im Contionous-Mode auch funktioniert.
1
#define LED_G BIT6
2
intmain(void)
3
{
4
// Stop watchdog timer to prevent time out reset
5
WDTCTL=WDTPW+WDTHOLD;
6
//Als Ausgang definieren
7
P1DIR|=LED_G;
8
P1SEL|=LED_G;//Sonderfunktion am Pin (Timerausgang für Register TACCTL1(?))
9
10
TACTL=TASSEL_2+MC_2;//SMCLK + Continious-Mode
11
12
TACCTL1|=OUTMOD_3;//PWM zwischen CCR1 & 0xFFFFh (?)(zumindest blinkt die LED)
13
TACCR1=40000;
14
while(1){}
15
}
Jetzt ist meine Frage ob es immernoch geht wenn ich den TACCTL0 Register
jetzt für die Capture-Funktion nehme?
Laut Diagramm2 würde er die Set/Reset Operationen ja normalerweise
zwischen CCR0 & CCR1 machen.
Ignoriert er CCR0 dann wenn ich den Register im Capture-Mode habe und
arbeitet wie oben zwischen CCR1 & 0xFFFFh oder benutzt der dann CCR0 &
CCR1 für den Set/Reset?
Bzw.
1
intmain(void)
2
{
3
// Stop watchdog timer to prevent time out reset
4
WDTCTL=WDTPW+WDTHOLD;
5
//Als Ausgang definieren
6
P1DIR|=LED_G;
7
/P1SEL|=LED_G;//Sonderfunktion am Pin (Timerausgang für Register TACCTL1(?))
8
9
P1DIR&=~BIT1;//Pin 1.1 als Eingang (Tabelle s.43 Datenblatt)
10
P1SEL|=BIT1;// Sonderfunktion Timer Capture für den Register TACCTL0 (?)
11
//Für Register TACCTL1 Capture-Mode müsste ich Pin 1.2 nehmen?
12
13
TACTL=TASSEL_2+MC_2;//SMCLK + Continious-Mode
14
15
TACCTL0=CAP+CM_1+CCIE;//Register 0 im Capture Mode
16
17
__bis_SR_register(GIE);
18
TACCTL1|=OUTMOD_3;//PWM zwischen CCR1 & 0xFFFFh (?)(zumindest blinkt die LED)
19
TACCR1=40000;
20
21
while(1){}
22
}
Würde dieser Grundgedanke funktionieren?
Also der 0-Register die Captures ausführen in seiner ISR und der
1-Register die PWM?
Zur Pin-Belegung:
Sind meine Annahmen da richtig?
http://www.ti.com/lit/ds/symlink/msp430g2553.pdf (ab s.43)
Sachen die mir beim rumprobieren aufgefallen sind:
-Wenn ich den Timer im Continious-Mode betreibe, funktioniert der
Interrupt (wenn ich ihn aktiviere) nur mit dem TACCTL0 Register.
Mit dem 1er Register kann ich keinen Interrupt auslösen.
Sprich:
Wie befürchtet nimmt er, sobald er einen CCR0-Wert bekommt durch nen
Capture, selbigen und führt die PWM-Befehle (Set/Reset) zwischen CCR0 &
CCR1 aus anstatt zwischen CCR1 & 0xFFFFh.
Jetzt ist natürlich meine Frage wie ich das sonst noch realisieren kann
das an einem Pin eine PWM eingelesen wird und ich an einem anderen eine
Ausgeben kann mit variablen duty Cycle.
(Hatte vor das Tastverhältnis zwischen CCR1 & dem Continious-Endwert
0xFFFFh zu regeln).
Hinzu kommt noch das kleine Problem das ich den Timer ja nicht nach
belieben zurücksetzen kann, wenn gleichzeitig noch ne PWM ausgegeben
werden soll.
Ich muss ja beim auslesen der eingehenden PWM irgendwas machen damit der
sich nicht mit den Timerwerten bei der Rechnung verrennt.(Er könnte ja
eine steigende Flanke bei 0xFF10h kriegen und die nächste bei 0x00ABh
und würde dann wahrscheinlich Murks für die Periodendauer rechnen).
Meine einzige Vermutung ist jetzt nen 2. Timer zuzuschalten der sich um
die PWM kümmert.
Nur leider hab ich noch nie mit dem Timer_B aus dem Userguide gearbeitet
:/
(http://www.ti.com/lit/ug/slau144j/slau144j.pdf ab Seite 374 kommt
Timer_B, Die Timer_A Register starten auf Seite 369).
Weiterhin finde ich auch keinen Pin der eine Zusatzfunktion für diesen
Timer erfüllt. (Immer nur TA0.1/TA0.0/TA1.0/TA1.1)
edit:
Fast vergessen...
Meine andere Idee wäre es, den Timer_A Register TACCTL2 für den Capture
zu nehmen.
(Sofern mir dieser zu Verfügung steht im Userguide ist er mit der
Bemerkung "Not present on MSP430 devices with Timer_A2 like MSP430F20xx
and other devices." gelistet.
Ich weiß jetzt nicht ob meiner zu "other devices" zählt...irgendwas mit
nem Timer_A2 kann ich aber auch nicht finden :/ )
Allerdings blicke ich, wie oben bereits erwähnt, mit den Pinbelegungen
nicht wirklich durch.
So wie ich das System bis jetzt verstanden habe gibt es keinen Pin der
Sonderfunktionen für den Timerregister TACCTL2 erfüllt.
Was bei mir die Frage aufkommen lässt wofür genau dieser Register gut
ist wenn man ihn weder für nen Capture noch für nen Compare nutzen kann?
Wäre wirklich dankbar wenn mir da noch jemand bei helfen könnte.
mfg Bobba