Forum: Mikrocontroller und Digitale Elektronik XMEGA256 A3BU - PWM


von Ron C. (Gast)


Lesenswert?

Hallo,

ich kriege die Krise..
1
PORTE.DIRSET = 1<<4;
2
3
4
void timer1CMPInit      ( TC1_t *tim )          
5
{    
6
  /*
7
  *  Hier wird ohne Hardware Pin Toggeln gearbeitet. Sollte von 
8
  *  außen der entsprechende Hardware Pin getoggelt werden, muss
9
  *  in das CTRLB Register ( ATXMEGA256A3BU ) noch TCx_CCxEN_bm gesetzt werden.
10
  */
11
  tim->CTRLA    = TIMER_PRESCALER_gc;                // Takt konfigurieren ( mit ggf. Vorteiler )
12
  tim->CTRLB    = ( TC_WGMODE_SINGLESLOPE_gc | TC1_CCAEN_bm );    // Compare Match 'A' aktivieren  
13
  tim->CCA    = TIMER_CALC;                    // Compare Match Wert
14
    tim->INTCTRLB  = TC_CCAINTLVL_HI_gc;                // Interrupt "Compare Match" aktivieren / Priorität des Interrupts festlegen
15
16
  
17
  PR.PRPC = 0x00;                            // Power einschalten
18
  PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;  // Interrupts freigeben ( sei() muss trodzdem sein! )
19
  
20
  sei();
21
}

Ich versuche an PORTE.4 eine PWM zu erzeugen.. Da passiert leider 
überhaupt nichts.. Was mache ich verkehrt?

von Bastian W. (jackfrost)


Lesenswert?

Wie sieht deine ISR für CCA aus ? Nur für PWM brauchst du den Interrupt 
nicht aktivieren

Gruß JackFrost

von Ron C. (Gast)


Lesenswert?

Bastian W. schrieb:
> Wie sieht deine ISR für CCA aus ? Nur für PWM brauchst du den
> Interrupt
> nicht aktivieren
>
> Gruß JackFrost

Stimmt. In die ISR sollte eigentlich nichts rein.

von Ron C. (Gast)


Angehängte Dateien:

Lesenswert?

Es gibt ja mehrere "OC1A" Kanäle. Wie genau stellt man denn diese ein? 
Ich brauche den an "PORTE Pin4" ?

von Bastian W. (jackfrost)


Lesenswert?

Das ist der Timer TCE1

Gruß JackFrost

von Ron C. (Gast)


Lesenswert?

Bastian W. schrieb:
> Das ist der Timer TCE1
>
> Gruß JackFrost

Ohje.. Peinlich! Also hat jeder Port einen eigenen Timer oder wie darf 
ich das verstehen?

von Bastian W. (jackfrost)


Lesenswert?

Normal gibt es für jeden Port einen bzw zwei Timer wenn der Port PWM 
hat.
Zur not den Simulator starten , dann Pausieren, im I/O Fenster siehst du 
die alle Timer usw.

Auch in der Datei für die Register kannst du das sehen. Einfach auf 
reinschauen und dann kannst du da suchen.

Gruß JackFrost

von Ron C. (Gast)


Lesenswert?

Moin,

ich werde noch wild.. Wieso funktioniert der "Compare Channel B , C , D" 
nicht?
Wenn ich es mit dem Compare Channel "A" mache, klappt alles wunderbar! 
Was habe ich übersehen?
1
  TCD0.CTRLA      = TC_CLKSEL_DIV1024_gc;    // Takt konfigurieren ( mit ggf. Vorteiler )
2
  TCD0.CTRLB      = TC_WGMODE_FRQ_gc;      
3
  TCD0.INTCTRLB    = TC_CCBINTLVL_HI_gc ;    // Interrupt "Compare Match" aktivieren / Priorität des Interrupts festlegen
4
  TCD0.PER      = 2000;
5
  TCD0.CCB      = 100;
6
  
7
  PR.PRPC  = 0x00;                              // Power einschalten
8
  PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;  // Interrupts freigeben ( sei() muss trodzdem sein! )
9
  
10
  sei();
11
  
12
    while (1) 
13
    {
14
15
    }
16
}
17
18
ISR( TCD0_CCB_vect )
19
{
20
  PORTD.OUTTGL = 1<<3;
21
  PORTD.OUTTGL = 1<<2;
22
  PORTD.OUTTGL = 1<<1;
23
}

von Bastian W. (jackfrost)


Lesenswert?

Was klappt denn nicht ?

Du hast eine PWM mit 50 % Tastgrad wenn du das so schreibst. Der CCB 
Interrupt wird ja einmal je durchlauf ausgeführt. Ist ja so wie ein 
Overflow nur zu einem anderen Zeitpunkt.

Du bist im Frequenzmodus, damit ist CCA die Oberegrenze. Wenn nun CCA 
auf 0 steht wird CCB mit 100 nie erreicht.

Frequenz != PWM. Willst du ne PWM mit fester Frequenz und variablem 
Tastgrad ?

Gruß JackFrost

von Ron C. (Gast)


Lesenswert?

Bastian W. schrieb:
> Was klappt denn nicht ?
>
> Du hast eine PWM mit 50 % Tastgrad wenn du das so schreibst. Der CCB
> Interrupt wird ja einmal je durchlauf ausgeführt. Ist ja so wie ein
> Overflow nur zu einem anderen Zeitpunkt.
>
> Du bist im Frequenzmodus, damit ist CCA die Oberegrenze. Wenn nun CCA
> auf 0 steht wird CCB mit 100 nie erreicht.
>
> Frequenz != PWM. Willst du ne PWM mit fester Frequenz und variablem
> Tastgrad ?
>
> Gruß JackFrost

Okay.. Ich möchte den Compare Match B Interrupt oder auch C usw..
in Abhängigkeit von TCCx.CCx auslösen lassen.

von J. Zimmermann (Gast)


Lesenswert?

Wieso schaltest Du die C ein, wenn Du Port-D Zähler verwendest (PR.PRPC 
= 0x00;)? Wird allerdings den Fehler nicht beheben, wenn es, wie Du 
schreibst mit CCA funzt hat. Beim XMEGA muss man im PRPx-Register auch 
das HIRES-Bit resetten, damit PWM funzt.
Die PORTDs hast Du sicher als PORTD.DIRSET=(1<<1) | (1<<2) | (1<<3); 
gesetzt?
mfg
Achim

von Bastian W. (jackfrost)


Lesenswert?

Ron C. schrieb:
> Okay.. Ich möchte den Compare Match B Interrupt oder auch C usw..
> in Abhängigkeit von TCCx.CCx auslösen lassen.

Dann willst du aber keine Variable PWM. Wenn du das machen willst müssen 
CCx < CCA sein, da CCA das Top im Frequenz Modus ist

PR.PRPC  = 0x00; brauchst du nicht da die Register alle mit 0x00 
initialierst sind.

Wenn du vorher PR.PRPx mit 1 beschrieben hast must du nach dem Reset von 
PR.PRPx den Timer Sicherheitshalber neu Einrichten.

Ich hab beim xMega64A3U, xMega32A4 und xMega32e5 bei den Timern nie das 
PR.PRPx resettet und die Timer laufen.

Gruß JackFrost

von Ron C. (Gast)


Lesenswert?

Bastian W. schrieb:
> Wenn du vorher PR.PRPx mit 1 beschrieben hast must du nach dem Reset von
> PR.PRPx den Timer Sicherheitshalber neu Einrichten.

Da hast du recht.

Hast du vill. noch eine Idee, wie ich den Entsprechenden Port raus 
bekommen kann, ohne wieder ein extra Parameter zu übergeben?
1
#define TIMER_PRx( _port ) ( ( & ( PR.PRPA     ) )[_port] )

Meine Struktur
1
typedef struct  
2
{
3
  TC0_t    *tim0; // Timer0
4
  TC1_t    *tim1; // Timer1
5
  
6
  struct  
7
  {
8
    tc0Ccx_t      compareMatchChannel; // Compare Match Channel
9
    uint16_t      perVal;  // maximaler Zählwert
10
    uint16_t      cmpVal; // Compare Match Wert
11
    tcxPrescaler_t    preVal;  // Prescaler Wert
12
  }tim0Cnfg;
13
14
  struct
15
  {
16
    tc1Ccx_t      compareMatchChannel; // Compare Match Channel
17
    uint16_t      perVal;  // maximaler Zählrwert
18
    uint16_t      cmpVal; // Compare Match Wert
19
    tcxPrescaler_t    preVal;  // Prescaler Wert
20
  }tim1Cnfg;  
21
  
22
}tcxInit_t;

Diese übergebe ich der Funktion die dann meinen Timer konfiguriert.
Oder setze ich generell gleich die Power Register auf "0x00"?

von Bastian W. (jackfrost)


Lesenswert?

Laut Datenblatt muss erst Power gesetzt werden und dann die Konfig. Aber 
das Register steht auf 0x00 nach einem Reset.

Gruß JackFrost

von J. Zimmermann (Gast)


Lesenswert?

Bastian W. schrieb:
> PR.PRPC  = 0x00; brauchst du nicht da die Register alle mit 0x00
> initialierst sind.

Bei Verwendung des ASF nicht immer richtig.

Bastian W. schrieb:
> müssen
> CCx < CCA sein

Es existieren 4 unabh. CCx-Hardware, muß also nicht sein.

Ron C. schrieb:
> #define TIMER_PRx( _port ) ( ( & ( PR.PRPA     ) )[_port] )

oder die Hose mit der Kneifzange anziehen ... viel einfacher ... XMEGA!

mfg
Achim

von Bastian W. (jackfrost)


Lesenswert?

J. Zimmermann schrieb:
>> müssen
>> CCx < CCA sein
>
> Es existieren 4 unabh. CCx-Hardware, muß also nicht sein.

Wenn der Timer im FRQ Modus ist, dann ist CCA Top. Wenn CCB/C/D nun 
größer sind werden sie nie auslösen da der Timer nur bis CCA läuft.

Gruß JackFrost

von J. Zimmermann (Gast)


Lesenswert?

@Bastian W.:
Absolut korrekt - war im falschen TC-Modus.
mfg
Achim

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.