Hallo, ich möchte ein PWM-Signal mit dem MSP auswerten. Ich habe allerdings überhaupt keine Idee, wie ich das PWM-Signal mit dem MSP analysieren soll. Wie komme ich denn an das Tastverhältnis der PWM? Gruß Marco
Das geht mit jedem mC: 100% ist die Zeit zwischen zwei gleichen Flanken. Das PWM-Tastverhältnis ist der Anteil, der von der gegengerichteten Flanke markiert ist - oder das Komplement. Ist das so schwierig, daß man da nicht selbst drauf kommen kann? Daniel Drüsendieb
Oder natürlich ganz stumpf Tiefpass/Integrierer -> ADC. Jenachdem was man über hat Timer oder ADC.
"Ist das so schwierig, daß man da nicht selbst drauf kommen kann" ne, was ne pwm ist und ein tastverhältnis weiß ich auch! mir ging es darum, wie man nun das signal, was man am controller anlegt auswertet. wenn ich es z.b. an einen adc port lege, wie ich dann per software daran komme. da habe ich keine idee. mit einem timer könnte man sicher die erste flanke nehmen, einen timer starten, dann sehen, wie weit es zur zweiten flanke ist usw. ist doch aber ein wenig umständlich, da man die ports andauern hin und her schalten muss, auf welche flanke sie reagieren müssen usw.
@ Marco B. >ne, was ne pwm ist und ein tastverhältnis weiß ich auch! >mir ging es darum, wie man nun das signal, was man am controller anlegt >auswertet. wenn ich es z.b. an einen adc port lege, wie ich dann per >software daran komme. da habe ich keine idee. Wenn du es per ADC machen willst, musst du einen RC-Tiefpass mit entsprechend niedriger Bandbreite davorschalten, die Bandbreite muss ca. 1/100 bis 1/1000 des der PWM-Frequenz betragen. >mit einem timer könnte man sicher die erste flanke nehmen, einen timer >starten, dann sehen, wie weit es zur zweiten flanke ist usw. ist doch >aber ein wenig umständlich, da man die ports andauern hin und her >schalten muss, auf welche flanke sie reagieren müssen usw. Überhaupt nicht. das sind eine handvoll Befehle, das fällt unter ferner liefen. Die Funktion die du suchst heisst Input Capture (ICP), kann der MSP auch. MFG Falk
Wie gesagt die Idee mit dem ADC ist nur dann sinnvoll wenn man keinen Timer mehr übrig hat. sonst ist der direkte Weg natürlich eleganter.
Hallo, ich bin nun nochmal dazu gekomen, mich damit zu beschäftigen. Allerings habe ich es noch nicht am Laufen. Ich habe nun das auszuwertende Signal an den Port 1.1 (TA0) gelelgt. Ich möchte nun die Periodenlänge messen und die Dauer des High-Pegels. Somit kann ich ja dann das Tastverhältnis berechnen. Das Problem ist nun, das kein Interrupt des Timers kommt. Er springt nicht in die ISR. Könnte es vielleicht an einer falschen Initialisierung liegen? Oder bin ich überhaupt auf dem richtigen Weg? Den Timer habe ich dann wie folgt initialisiert:
1 | void InitTimer(void) |
2 | {
|
3 | TACTL = TASSEL_2 + MC_2 + ID_3 + TACLR; // SMCLK, continuous, Teiler 8 |
4 | // 1MHz
|
5 | TACCTL0= CM_1 + SCS + CCIS_0 + CAP + CCIE; // steigende Flanke, |
6 | // synchronisiert
|
7 | // TA0, Capture mode,
|
8 | }
|
Der externe Quarz 8MHz wird zuvor schon wie folgt initialisiert. er soll auch für Baudratenerzeugung des uart verwendet werden. Die Uart Schnittstelle funktioniert einwandfrei.:
1 | BCSCTL1 &= ~XT2OFF; // XT2on, externen Resonator anschalten (8MHz) |
2 | do
|
3 | {
|
4 | IFG1 &= ~OFIFG; // Clear OSCFault flag |
5 | wait(255); // Time for flag to set |
6 | }
|
7 | while ((IFG1 & OFIFG)); // OSCFault flag still set? |
8 | BCSCTL2 |= SELM_2 + SELS; // MCLK = SMCLK = XT2 (safe) |
Die ISR des Timers sieht wie folgt aus:
1 | #pragma vector=TIMERA0_VECTOR
|
2 | __interrupt void Timer_A0 (void) |
3 | {
|
4 | if(flanke == 0 && ready == 0)// Wenn erste steigende Flanke kommt... |
5 | {
|
6 | rise= TACCR0; // Zählerstand speichern |
7 | periode= rise - start; // Periodenlänge berechnen |
8 | start= rise; // Wert für spätere weiterverarbeitung |
9 | // zwischen speichern
|
10 | flanke++; |
11 | ready= 1; // Wenn ready 1 ist, dürfen die Werte |
12 | // ausgegeben werden
|
13 | TACCTL0 |= CM_2; // auf fallende Flanke umschalten |
14 | }
|
15 | else if(flanke == 1 && ready == 0) // Wenn die fallende Flanke kommt |
16 | {
|
17 | fall= TACCR0; // Zählerstand speichern |
18 | high_time= fall - rise; // High-Zeit berechnen |
19 | flanke= 0; |
20 | TACCTL0 |= CM_1; // Auf steigende Flanke umschalten |
21 | }
|
22 | }/* __interrupt void Timer_A0 (void) */ |
Vieleicht noch die Initialisierung der Ports:
1 | void InitPorts(void) |
2 | {
|
3 | P1DIR=0x00; // Port1 = Input |
4 | P2DIR=0x80; // Port2 = Output (Port 2.7 als "ENABLE") |
5 | P4DIR=0xFF; // Port 4 = Output (8 Datenleitungen zum LCD) |
6 | P5DIR=0x1F; // Port 5 = Output (RS, R/W und E vom LCD an 44, 45 |
7 | // und 46 (entspricht P 5.0, 5.1, 5.2))
|
8 | P1SEL=0x00; // Alle Ports als GPIO nutzen |
9 | P2SEL=0x02; |
10 | P3SEL=0x30; // Port 3 als UART nutzen |
11 | P4SEL=0x00; // Alle Ports als GPIO nutzen |
12 | P5SEL=0x00; // Alle Ports als GPIO nutzen |
13 | |
14 | P5OUT=0x01; // Initial nur E (clock) auf HIGH, RS und R/W auf LOW |
15 | P4OUT=0x00; // Ports mit Null initialisieren |
16 | P2OUT=0x00; |
17 | }/* void InitPorts(void) */ |
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.