Forum: Mikrocontroller und Digitale Elektronik Timer-PWM mit ATxmega256A3U


von Max (Gast)


Lesenswert?

Moin!

Ich bin neu ins Thema Microcontroller eingestiegen und möchte eine PWM 
mittels Timer für eine LED generieren.
Ich habe folgenden Code geschrieben:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#ifndef F_CPU
5
#define F_CPU   2000000
6
#endif
7
8
void pwm_init(void);
9
10
int main(void)
11
{   
12
    pwm_init();
13
    TCC0_CCABUF = 0x7FFF;                   //set the duty cycle as 50%
14
    while((TCC0_INTFLAGS & 0x01) == 0);     //wait for the new compare 
15
    TCC0_INTFLAGS = 0x00;
16
17
    while(1);  
18
}
19
20
void pwm_init() 
21
{   
22
    PORTE_DIRSET = PIN5_bm;                 //PORTE Pin5
23
    TCC1_PER = 0xFFFF;   
24
    TCC1_CTRLB = TC_WGMODE_SINGLESLOPE_gc;  //Single slope mode
25
    TCC1_CTRLB = TC1_CCAEN_bm;              //channel selection CCAEN
26
    TCC1_CTRLA = TC_CLKSEL_DIV2_gc;         //clock selection clk/2
27
}

Kann das so funktionieren? Die LED leuchtet, ich bin mir jedoch nicht 
sicher, ob das nur daran liegt, das der PORT 5 in der pwm_init() 
geschaltet wird.

Ich habe einmal mit einem Oszi gemessen und keine PWM gesehen. 
Allerdings bin ich mir auch nicht sicher, ob ich richtig gemessen habe.

Vielleicht sieht jemand das Problem.

Viele Grüße,
Max

von Karl H. (kbuchegg)


Lesenswert?

Max schrieb:

> Kann das so funktionieren? Die LED leuchtet, ich bin mir jedoch nicht
> sicher, ob das nur daran liegt, das der PORT 5 in der pwm_init()
> geschaltet wird.

Das lässt sich ja leicht rausfinden. Verändere den Compare Wert
1
    TCC0_CCABUF = 0x7FFF;                   //set the duty cycle as 50%
und wenn die LED die scheinbare Helligkeit ändert, dann läuft die PWM. 
Hier aber nicht kleckern. Um einen deutlichen Unterschied zu sehen ruhig 
in die vollen greifen und zb
1
    TCC0_CCABUF = 0x00FF;

von Karl H. (kbuchegg)


Lesenswert?

1
    TCC1_CTRLB = TC_WGMODE_SINGLESLOPE_gc;  //Single slope mode
2
    TCC1_CTRLB = TC1_CCAEN_bm;              //channel selection CCAEN

2 Zuweisungen an ein und dasselbe Kontroll-Register?
Ich denke nicht, dass das das Beabsichtigte bewirkt.

Es gibt zwar Ausnahmen mit den Port-Set und Port-Clear Registern, aber 
der Normalfall ist nun mal, das mit einer Zuweisung das komplette 
Register (wie bei einer Variablen) neu beschrieben wird, wodurch die 
2.te Zuweisung die erste wieder löscht.

von Max (Gast)


Lesenswert?

Ich hab jetzt meinen Code nach bestem Wissen korrigiert, kriege aber 
immer noch nicht eine Dimmung hin. Die LED ist nur an, keine PWM:
1
#include <avr/io.h>
2
#define REG16_MAXIMUM 0xFFFE
3
4
int main(void)
5
{    
6
  
7
  OSC_CTRL = CLK_SCLKSEL_RC32M_gc; // 32MHz Clock
8
  
9
  
10
  PORTE_DIR = PIN5_bm;                                  // set Pin5 as output
11
  TCE1_CTRLB = TC_WGMODE_SINGLESLOPE_gc | TC1_CCBEN_bm; // set PWM to single slope and CCBE as CompareRegister
12
  TCE1_CTRLD = 0;                                        // disable events
13
  TCE1_PER = REG16_MAXIMUM;                             // period 
14
  TCE1_CCBBUF = 0x000F;                  // duty cycle
15
  //TCE1_CTRLFCLR = 0x10;                    // reset flag when counting up from zero
16
  TCE1_CTRLA = TC_CLKSEL_DIV8_gc;                       // clock divider
17
  
18
    while(1);  
19
}

Ich nutze Port E und den Timer1 an Port E. Angesteuert wird PE5.

Vielleicht kennt sich jemand mit dem xMega gut aus.

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
Noch kein Account? Hier anmelden.