Mehrere PWM-Kanäle mit ATXmega

Gast #2471955
Lesenswert?

Hallo,

ich stehe gerade vor einem Problem mit einem ATXmega32A4, programmiert 
mit dem AVR-Studio. Ich möchte gerne jeweils drei PWM-Kanäle en bloc 
über einen USART setzen, jedoch werden die Werte scheinbar nicht korrekt 
in die Register geschrieben.

Folgende Initialisierung habe ich:

/* Initialize PWM outputs on PORTC and PORTD.
   PWM frequency = 730Hz
   resolution = 8bit */
TCC0.CTRLA    = TC_CLKSEL_DIV64_gc;
TCC0.CTRLB    = TC_WGMODE_SS_gc | TC0_CCAEN_bm | TC0_CCBEN_bm;
TCC0.CTRLC    = 0;
TCC0.CTRLD    = TC_EVACT_OFF_gc;
TCC0.CTRLE    = 0;
TCC0.PER      = 255;
TCC0.CCABUF   = 0;
TCC0.CCBBUF   = 0;

TCC1.CTRLA    = TC_CLKSEL_DIV64_gc;
TCC1.CTRLB    = TC_WGMODE_SS_gc | TC1_CCAEN_bm | TC1_CCBEN_bm;
TCC1.CTRLC    = 0;
TCC1.CTRLD    = TC_EVACT_OFF_gc;
TCC1.CTRLE    = 0;
TCC1.PER      = 255;
TCC1.CCABUF   = 0;
TCC1.CCBBUF   = 0;

TCD0.CTRLA    = TC_CLKSEL_DIV64_gc;
TCD0.CTRLB    = TC_WGMODE_SS_gc | TC0_CCBEN_bm | TC0_CCCEN_bm;
TCD0.CTRLC    = 0;
TCD0.CTRLD    = TC_EVACT_OFF_gc;
TCD0.CTRLE    = 0;
TCD0.PER      = 255;
TCD0.CCBBUF   = 0;
TCD0.CCCBUF   = 0;

Das Setzen erfolgt durch die folgenden Zeilen:

if (PC_Interface_Buffer[3] == 0)
{
   /* Set PWM1, 2 and 3 */
   TCD0.CCCBUF = PC_Interface_Buffer[4];
   TCD0.CCBBUF = PC_Interface_Buffer[5];
   TCC1.CCABUF = PC_Interface_Buffer[6];
}
else
{
/* Set PWM4, 5 and 6 */
   TCC1.CCBBUF = PC_Interface_Buffer[4];
   TCC0.CCBBUF = PC_Interface_Buffer[5];
   TCC0.CCABUF = PC_Interface_Buffer[6];
}

Wenn ich jetzt in TCD0.CCCBUF den Wert 255 schreibe und in TCD0.CCBBUF 
0, so bleiben beide PWM-Kanäle auf 0 (geprüft mit Oszi). Vertausche ich 
die Werte (TCD0.CCCBUF jetzt 255), so liegt an OC0B (also dem anderen) 
das Signal an, OC0C bleibt 0.

Mir scheint es, als würden die Werte nicht korrekt in die Register 
geschrieben werden. Daher hatte ich auch schon CCx statt CCxBUF 
probiert, mit dem gleichen Resultat.

Sonst noch jemand eine Idee? Schreibe ich nur ein Register in der 
gleichen Routine, geht es merkwürdigerweise.

Grüße

Christop
Persönliche Seite #2475668
Lesenswert?

Knut Ballhause schrieb:
> Dein Code sollte sich mal darauf einigen, welche Register überhaupt
> beschrieben werden sollen. Sowohl die Timer, als auch die
> OCR/PWM-Register werden mit abweichenden Bit/Registernamen definiert.

Die Initialisierung passt soweit, zumindest stimmen die Registernamen 
alle zueinander. Benutzt werden scheinbar 0A und 0B sowie 1A und 1B von 
TimerC sowie 0B und 0C von Timer D (wobei 0A scheinbar initialisiert 
wird, aber nicht in dem zweiten Teil des Codes genutzt wird.

> Überprüfe nochmal jede einzelne Zeile Deines Codes!

Das würde ich auch raten, allerdings würde ich auch mal genau 
überprüfen, ob die Werte aus dem UART (sieht zumindest danach aus) 
korrekt gelesen werden oder ob da schon falsche Werte ankommen.

Ob man CCx oder CCxBUF verwendet, sollte für die Funktion erstmal keine 
Rolle spielen (beeinflusst nur den Update-Zeitpunkt).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren