Forum: Mikrocontroller und Digitale Elektronik msp430 probleme mit pwm modulierung


von Heiner B. (synergy1337)


Angehängte Dateien:

Lesenswert?

hi,
ich wollte mit meinem msp430g2211 (vom launchpad) ein pwm signal sinus 
förmig modulieren. dazu habe ich den timer in den upmode gesetzt und 
dann in der ISR den ausgang entweder auf high oder low gesetzt und dann 
den timer auf mithilfe einer vorberechneten sinus tabelle entsprechend 
aktualisiert. nun klappt das gut für große werte jedoch tritt ein 
seltsames verhalten bei werten unter ca. 85 auf, dazu habe ich in die 
sinus tabelle testweise nur 2 werte eingetragen (je ein wert für high, 
der nächste für low) um das zu testen:
code:

#include  <msp430g2211.h>

int winkel=0;
int out=0;
int hilf=0;

const int sinus[]={999,87}; //sine table, immer 2 werte jeweils low und 
high


*/
//float cosinus[]={};
void main(void)
{
   WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
 //unsigned long counter=0;

  P1DIR = 0x40;                             // P1.6 output (green LED)
  P1OUT = 0;                                // LED off
  TACTL = TASSEL_2 + MC_1;                  // SMCLK, upmode
  TACCR0 = 10000;
  _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0 w/ interrupt
}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{

   hilf = sinus[winkel];
   out^=0x40;
  if(hilf > 0)
  {

      P1OUT = out;         // Toggle output


  }

    TACCR0 = hilf;         // reset upper timer limit

    winkel = (winkel+1)%2;      // index for sine table

}
im anhang 2 bilder vom oszi, das 1. für "hohe werte" der 2. für nidrige 
mit dem seltsamen verhalten

von Jörg S. (joerg-s)


Lesenswert?

Wie viele Takte brauch denn der MSP um die ISR abzuarbeiten? Nicht das 
der Timer überlauft wen er noch überhaupt nicht mit der ISR fertig ist.

von Max G. (l0wside) Benutzerseite


Lesenswert?

Jörg S. schrieb:
> Wie viele Takte brauch denn der MSP um die ISR abzuarbeiten? Nicht das
> der Timer überlauft wen er noch überhaupt nicht mit der ISR fertig ist.

unterschreib - genau das Verhalten hatte ich auch schon.

Für einen schönen Sinus oberhalb von ein paar Hertz wirst Du mit Deinem 
Ansatz (ISR+GPIO) nicht arg weit kommen. Ich habe mal mit dem F2012 
einen BLDC-Controller nach Deinem Ansatz aufgebaut, das ging zwar 
irgendwie, aber das Ergebnis drehte und klang nicht wirklich schön.

Wenn Du nur einen PWM brauchst, nimm den Timer A und lasse mit ihm den 
zugehörigen Ausgang wackeln.  Wenn Du mehr als einen PWM brauchst, nimm 
einen größeren MSP430.

Max

von Heiner B. (synergy1337)


Lesenswert?

hm
ja anscheinend läuft er über,
habe mir jetzt grad was anderes überlegt, mithilfe von CCR0 und CCR1 
(btw, ist das das gleiche wie TACCR0 iwie wird das überall synonym 
verwendet)
kann man das ja super machen wenn man CCRO auf die pwm frequenz setzt 
und dann in der ISR immer CCR1 updatet dann hat man quasi die low zeit 
direkt als überbleibsel, momentan hauts aber iwie noch nicht hin

von Max G. (l0wside) Benutzerseite


Lesenswert?

Heiner B. schrieb:
> hm
> ja anscheinend läuft er über,
> habe mir jetzt grad was anderes überlegt, mithilfe von CCR0 und CCR1
> (btw, ist das das gleiche wie TACCR0 iwie wird das überall synonym
> verwendet)
> kann man das ja super machen wenn man CCRO auf die pwm frequenz setzt
> und dann in der ISR immer CCR1 updatet dann hat man quasi die low zeit
> direkt als überbleibsel, momentan hauts aber iwie noch nicht hin

Wenn ich Deinen Text richtig verstehe, hast Du das System der 
PWM-Erzeugung verstanden. Zeige doch mal deinen Code, dann wird 
vielleicht auch klar, was nicht tut.

Wenn Du nur einen Timer hast, sind TACCR0 und CCR0 identisch. Wenn Du 
mehr Timer hast, z.B. Timer B1, hast Du dann auch TB1CCR0 usw., und die 
Kurzbezeichnungen reichen nicht mehr aus.

Max

von Heiner B. (synergy1337)


Lesenswert?

ok also funktionier doch,
hab die werte in der sinus tabelle alle um 85 erhöht um den lag 
auszugleichen,
ne andre frage, zusätzlich müsste ich noch ne sinus welle um 90° 
verschoben zur 1. auf nem andren pin ausgeben können, kann man die iwie 
direkt aus dieser ableiten oder brauch ich dann quasi alles nochmal auf 
timer b ? bzw könnten die sich in die quere kommen?
hier mal der momentane code:

#include  <msp430g2211.h>
int winkel=0;
        //sinus tabelle,um 85 erhöht

const int sinus_a[]={585, 616, 647, 678, 709, 739, 769, 797, 825, 852, 
878, 903, 927,949, 970, 989, 1007, 1023, 1037, 1049, 1060, 1069, 1076, 
1081, 1084,1085, 1084, 1081, 1076, 1069, 1060, 1049, 1037, 1023, 1007, 
989, 970, 949, 927, 903, 878, 852, 825, 797, 769, 739, 709, 678, 647, 
616, 585, 554, 523, 492, 461, 431, 401, 373, 345, 318, 292, 267, 243, 
221, 200, 181, 163, 147, 133, 121, 110, 101, 94, 89, 86, 85, 86, 89, 94, 
101, 110, 121, 133, 147, 163, 181, 200, 221, 243, 267, 292, 318, 345, 
373, 401, 431, 461, 492, 523, 554};

void main(void)
{
   WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer

  P1DIR = 0x40;                             // P1.6 output (green LED)
  P1SEL = 0x40;                             // timer output

  P1OUT = 0;                                // LED off
  CCTL0 = CCIE+OUTMOD_7  ;                   // CCR0 interrupt enabled
  CCTL1 = OUTMOD_7;
  TACTL = TASSEL_2 + MC_1;                  // SMCLK, up mode
  CCR0 = 1085;
  CCR1 = 500;

  _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0 w/ interrupt
}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  TACCR1 = sinus_a[winkel];
    winkel = (winkel+1)%100; // index für sinustabelle

}

von Max G. (l0wside) Benutzerseite


Lesenswert?

Heiner B. schrieb:
> ok also funktionier doch,

Prima! Code sieht auch ganz sinnvoll aus.

> ne andre frage, zusätzlich müsste ich noch ne sinus welle um 90°
> verschoben zur 1. auf nem andren pin ausgeben können, kann man die iwie
> direkt aus dieser ableiten oder brauch ich dann quasi alles nochmal auf
> timer b ? bzw könnten die sich in die quere kommen?

Du brauchst ein zweites PWM-Modul, der G2211 hat aber nur eines. Du 
wirst also wohl entweder Deine alte Lösung mit der ISR wieder nehmen 
müssen oder ein größeres Derivat nehmen (Lieferbarkeit und notwendigen 
Programmieradapter beachten!).

Ich hatte fast exakt Deine Probleme und bin beim MSP430F5308 gelandet. 
Den kann man aber wieder nicht mit dem ez430 programmieren :-(

Max

von Heiner B. (synergy1337)


Lesenswert?

eh ja, habs auch grad gemerkt dasses keine timer b gibt, =( wobei ja 
eigtl ein weiteres capture compare register (also ccr2) auch schon 
gereicht hätte, aber das gibts auch nicht argh!
also im up-down modus steht bei der beschreibung iwas von 4 
verschiedenen frquenzen die man erzeugen können soll, mal schaun ob sich 
da was machen lässt, welchen controller könntet ihr mir denn dann 
empfehlen den man für diese aufgabe benutzten kann und eben möglichst 
mit dem launchpad (nicht das gleiche wie ez430 ???) programmieren kann

von Max G. (l0wside) Benutzerseite


Lesenswert?

Wegen Programmierbarkeit schau mal auf 
http://www.ti.com/lit/ug/slau278f/slau278f.pdf, Seite 14.

Ansonsten ist die parametrische Suche von TI ganz brauchbar. Du musst 
halt parallel schauen, was tatsächlich bei den Distributoren lieferbar 
ist.

Max

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.