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
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
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
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
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
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
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
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
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
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.
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:
1 | void InitEPwmTimer() |
2 | {
|
3 | .....
|
4 | |
5 | |
6 | EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRD_CMPA; // Select INT CMPA event |
7 | EPwm1Regs.ETSEL.bit.INTEN = 0x1; // Enable INT |
8 | EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Take the first Event |
9 | .....
|
10 | }
|
In der PWM_ISR:
1 | // Interrupt routine for PWM1
|
2 | interrupt void epwm1_timer_isr(void) |
3 | {
|
4 | |
5 | ....
|
6 | EPwm1TimerIntCount++; |
7 | |
8 | // Toggle Pin 16
|
9 | GpioDataRegs.GPATOGGLE.bit.GPIO16=1; |
10 | |
11 | // Set different INT-Trigger-Values
|
12 | if(EPwm1Regs.ETSEL.bit.INTSEL == ET_CTRD_CMPA) |
13 | {
|
14 | EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRU_CMPA; |
15 | }
|
16 | else
|
17 | {
|
18 | EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRD_CMPA; |
19 | }
|
20 | |
21 | // Clear INT flag for this timer
|
22 | EPwm1Regs.ETCLR.bit.INT = 1; |
23 | |
24 | // Acknowledge this interrupt to receive more interrupts from group 3
|
25 | PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; |
26 | .....
|
27 | }
|
Denke nicht das es die "feine Art" ist, aber es funktioniert. Danke euch allen! Viele Grüße 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.