www.mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP PWM Registerwerte TMS320F28335


Autor: Max0804 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Ich bin gerade dabei eine einfach PWM zu realisieren.
Die DSP läuft mit 150 Mhz und ich habe den Systemclock für die PWM mit 
15 vorgeteilt.
Welchen Wert im TBPRD Register muss man denn da reinladen?
Die Initialisierung sieht so aus:

   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;      // Stop all the TB clocks
   EDIS;
   // Setup Sync
   EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;  // Pass through


   // Allow each timer to be sync'ed

   EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;

   //Phase
   EPwm1Regs.TBPHS.half.TBPHS = 0;


   //Clock div 15;
   EPwm1Regs.TBCTL.bit.HSPCLKDIV=5;
   EPwm1Regs.TBCTL.bit.CLKDIV=3;



   EPwm1Regs.TBPRD = 18750;
   EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;    // Count up
   EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero 
event
   EPwm1Regs.ETSEL.bit.INTEN = PWM1_INT_ENABLE;  // Enable INT
   EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 1st 
event


   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;         // Start all the 
timers synced
   EDIS;

Mit dem Wert TBPRD = 18750 läuft die PWM mit exakt 10 ms. So wie 
gewollt. Aber warum gerade der Wert? Habe das Manual gelesen (SPRU791F) 
da steht eine Formel drin (TPWM = (TBPRD + 1) x TTBCLK) aber die passt 
irgendwie nicht zu dem Wert vom TBPRD. Ist die Formel falsch, oder mache 
ich da einen Denkfehler?
Hoffe jemand bringt da bei mir Licht ins Dunkel! ;)

Viele Grüße
Max

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Max0804 schrieb:
> //Clock div 15;
>    EPwm1Regs.TBCTL.bit.HSPCLKDIV=5;
>    EPwm1Regs.TBCTL.bit.CLKDIV=3;

Es ist zwar schon eine ganze Weile her, aber ich glaube so ging das 
nicht. HSPCLKDIV kann - meine ich - nicht den Wert 5 annehmen. Im 
Binaermuster wäre das 101 ... das wird im Teiler irgendwas mit 10 sein 
vermute ich.
Gleiches gilt für CLKDIV... 3 gibt es so nicht. Das sind Binaer 011 und 
dürfte vom Teiler wohl bei 8 sein. Das heisst du teilst nicht durch 15 
sondern durch 8 * 10 = 80

Vermutlich liegt da dein Fehler.

Ich würde dir empfehlen Magic Numbers zu vermeiden. Benutze doch die 
freundlicherweise von TI mitgelieferten Definitions... glaube TB_DIV1 
u.s.w.
Dannn kommt es nicht zu solchen Fehlern.

- gerd

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerade nochmal nachgerechnet... was ich oben geschrieben habe stimmt so. 
Es kommt auch deine PWM-Periodendauer raus. Du teilst die 150 MHz System 
takt nicht durch 15 sondern durch 80.

- gerd

Autor: Max0804 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gerd schrieb:
> Gerade nochmal nachgerechnet... was ich oben geschrieben habe stimmt so.
> Es kommt auch deine PWM-Periodendauer raus. Du teilst die 150 MHz System
> takt nicht durch 15 sondern durch 80.

Es passt. Dankeschön. Bin normalerweise immer in BIN unterwegs. Doch 
heute morgen dachte ich mir, machen wir mal "schnell", und solche Fehler 
entstehen leider dabei! :(

Nochmals vielen Dank!


Grüße
Max

Autor: Max0804 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Gibt es eine Möglichkeit die PWM-Pins umzulegen? Über Mux scheint es 
laut Datenblatt (Tabelle) nicht zu funktionieren!
Soll man bei Statusänderung (Also PWM-Signal low=> high und high => low) 
einen GPIO Toggeln, oder wie wird das bei dem Controller gemacht?

Viele Grüße

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die eigentlichen "PWM-Pins" sind meines Wissens nach fest. Sicherlich 
kann man über einen entsprechenden Interrupt auch eine akurate 
Workaround-Lösung für andere Pins hinbekommen (selbst habe ich das aber 
nie ausprobiert).

- gerd

Autor: Max0804 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gerd schrieb:
> Sicherlich
> kann man über einen entsprechenden Interrupt auch eine akurate
> Workaround-Lösung für andere Pins hinbekommen (selbst habe ich das aber
> nie ausprobiert).

Habe ich bereits versucht, also die GPIOs in der ISR der PWM zu toggeln. 
Allerdings entstehen dann signale mit einem Duty-Cycle von 50%.
Kann es sein, das man da über die Action-Register irgendwie ran kommt? 
Möchte nämlich keine Lösung, bei der man die Registerwerte in der ISR 
ändern muss.

Viele Grüße

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Puh, das sind Sachen die ich nichtmehr ganz im Gedächnis habe.
Ich meine mich zu erinnern, dass man mit dem "Action Qualifier" oder 
so ähnlich (kann auch ein ganz anderes Register gewesen sein - wie 
gesagt, alles nur aus dem Gedächnis) die Interrupt-Auslösemechanismen 
festlegen kann. Sprich du kannst bei "Compare on match" als auch bei 
"Zero" einen Interrupt auslösen. Damit sollte sich dann das eigentliche 
PWM-Signal 1:1 abbilden lassen (so die Theorie).

- gerd

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, das hat mir nu keine Ruhe gelassen und ich hab nochmal im Dokument 
spru791f.pdf nachgeschaut. Der Event Trigger ist dein Freund! Siehe 
Kapitel 2.8 Seite 64ff.

- gerd

Autor: Micha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Max0804 schrieb:
> Habe ich bereits versucht, also die GPIOs in der ISR der PWM zu toggeln.
> Allerdings entstehen dann signale mit einem Duty-Cycle von 50%.
> Kann es sein, das man da über die Action-Register irgendwie ran kommt?
> Möchte nämlich keine Lösung, bei der man die Registerwerte in der ISR
> ändern muss.
Du musst mit mehreren Interrupts arbeiten wenn du das so lösen möchtest. 
Sinnvoller/Einfacher/Flexibler/Performanter ist es allerdings die 
entsprechenden Pins zu nehmen.

Autor: Max0804 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gerd schrieb:
> Ok, das hat mir nu keine Ruhe gelassen und ich hab nochmal im Dokument
> spru791f.pdf nachgeschaut. Der Event Trigger ist dein Freund! Siehe
> Kapitel 2.8 Seite 64ff.

Danke Gerd! Falls jemand ein ähnliches Problem hat, habe es jetzt so 
gelöst:

In der Initialisierung:
void InitEPwmTimer()
{
.....


   EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRD_CMPA;     // Select INT CMPA event
   EPwm1Regs.ETSEL.bit.INTEN = 0x1;               // Enable INT
   EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;            // Take the first Event
.....
}

In der PWM_ISR:
// Interrupt routine for PWM1
interrupt void epwm1_timer_isr(void)
{
  
....  
 EPwm1TimerIntCount++;
   
   // Toggle Pin 16
   GpioDataRegs.GPATOGGLE.bit.GPIO16=1;

   // Set different INT-Trigger-Values
   if(EPwm1Regs.ETSEL.bit.INTSEL == ET_CTRD_CMPA)
   {
      EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRU_CMPA;
   }
   else
   {
      EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRD_CMPA;
   }
   
   // Clear INT flag for this timer
    EPwm1Regs.ETCLR.bit.INT = 1;

   // Acknowledge this interrupt to receive more interrupts from group 3
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
.....
}

Denke nicht das es die "feine Art" ist, aber es funktioniert.

Danke euch allen!

Viele Grüße
Max

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.