Forum: Mikrocontroller und Digitale Elektronik PWM mit Timerinterrupt


von Gustav (Gast)


Lesenswert?

Hallo,

ich versuche ein Soft-PWM-Signal über einen Timerinterrupt mit einem 
XMEGA8E5 auszugeben leider gelingt mir das noch nicht und ich weiß nicht 
warum... kann mir bitte einer vllt einen Tipp geben?

Zunächst habe ich versucht eine Soft-PWM ohne Timerinterrupt auszugeben 
was auch gut klappt:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
void clock_init (void)
5
{
6
  OSC.CTRL |= OSC_RC8MEN_bm; /*Oszillator auf 8 Mhz einstellen*/
7
  while(!(OSC.STATUS & OSC_RC8MRDY_bm)); /*Warten bis der Oszillator
8
  bereit ist*/
9
  CCP = CCP_IOREG_gc; /*Schützt I/O Register, Interrupts werden
10
  ignoriert*/
11
  CLK.CTRL = (CLK.CTRL &~ CLK_SCLKSEL_gm) | CLK_SCLKSEL_RC8M_gc;
12
  /*aktiviert den internen Oszillator*/
13
}
14
15
void interrupt_init (void)
16
{
17
  PMIC.CTRL |= PMIC_LOLVLEN_bm; /*Interrupt eingeschaltet*/
18
  sei(); /*Interrupt freischalten*/
19
}
20
21
void timer4_init (void)
22
{
23
  TCC4.CTRLA = TC45_CLKSEL_DIV256_gc; /*Vorteiler auf 8 eingestellt*/
24
  TCC4.CTRLB = TC45_WGMODE_NORMAL_gc; /* Timer auf normal Mode (hochzählend) eingestellt */
25
  TCC4.PER = 32768; //Timer vorladen 65436 überlauf nach 1s
26
  TCC4.INTCTRLA = TC45_OVFINTLVL_LO_gc; /*Interrupt Modus aktiv*/
27
  TCC4.INTFLAGS = TC4_OVFIF_bm;
28
}
29
30
int main(void)
31
{
32
  uint8_t pwm_duty_cicle = 50;
33
  uint8_t pwm_phase = 0; 
34
  
35
  PORTD_DIRSET = PIN6_bm;
36
    
37
  clock_init ();
38
  timer4_init();
39
  interrupt_init();  
40
  
41
  
42
  while(1)
43
    {    
44
    if( pwm_duty_cicle == pwm_phase )
45
    {
46
      PORTD.OUTSET = PIN6_bm; // active low LED aus
47
    }
48
    pwm_phase++;
49
    if( pwm_phase == 100 )
50
    {
51
      pwm_phase = 0;
52
      PORTD.OUTCLR = PIN6_bm; // active low LED an
53
    }
54
  }
55
}


jetzt der Quellcode mit Timerinterrupt nur irgendwie wird die 
if-schleife nie abgearbeitet obwohl in den Interrupt reingesprungen wird 
(habe ich über toggeln einer LED getestet ist im Moment auskommentiert)

Was mache ich falsch?
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
void clock_init (void)
5
{
6
  OSC.CTRL |= OSC_RC8MEN_bm; /*Oszillator auf 8 Mhz einstellen*/
7
  while(!(OSC.STATUS & OSC_RC8MRDY_bm)); /*Warten bis der Oszillator
8
  bereit ist*/
9
  CCP = CCP_IOREG_gc; /*Schützt I/O Register, Interrupts werden
10
  ignoriert*/
11
  CLK.CTRL = (CLK.CTRL &~ CLK_SCLKSEL_gm) | CLK_SCLKSEL_RC8M_gc;
12
  /*aktiviert den internen Oszillator*/
13
}
14
15
void interrupt_init (void)
16
{
17
  PMIC.CTRL |= PMIC_LOLVLEN_bm; /*Interrupt eingeschaltet*/
18
  sei(); /*Interrupt freischalten*/
19
}
20
21
void timer4_init (void)
22
{
23
  TCC4.CTRLA = TC45_CLKSEL_DIV256_gc; /*Vorteiler auf 8 eingestellt*/
24
  TCC4.CTRLB = TC45_WGMODE_NORMAL_gc; /* Timer auf normal Mode (hochzählend) eingestellt */
25
  TCC4.PER = 32768; //Timer vorladen 65436 überlauf nach 1s
26
  TCC4.INTCTRLA = TC45_OVFINTLVL_LO_gc; /*Interrupt Modus aktiv*/
27
  TCC4.INTFLAGS = TC4_OVFIF_bm;
28
}
29
30
uint8_t flag;
31
32
int main(void)
33
{
34
  uint8_t pwm_duty_cicle = 10;
35
  uint8_t pwm_phase = 0; 
36
  
37
  PORTD_DIRSET = PIN6_bm;
38
    
39
  clock_init ();
40
  timer4_init();
41
  interrupt_init();  
42
  
43
  if(flag == 5)
44
  {
45
    if( pwm_duty_cicle == pwm_phase )
46
    {
47
      PORTD.OUTSET = PIN6_bm; // active low LED aus
48
    }
49
    pwm_phase++;
50
    
51
    if( pwm_phase == 100 )
52
    {
53
    pwm_phase = 0;
54
    PORTD.OUTCLR = PIN6_bm; // active low LED an
55
    }
56
  }
57
  
58
  while(1)
59
    {    
60
    
61
  }
62
}
63
64
65
ISR(TCC4_OVF_vect)
66
{
67
  TCC4.INTFLAGS = TC4_OVFIF_bm;
68
  //PORTD.OUTTGL = PIN6_bm;
69
  flag ++;
70
}

von Gustav (Gast)


Lesenswert?

Hat keiner eine Idee woran es liegen könnte?

von Michael K. (Gast)


Lesenswert?

Gustav schrieb:
> uint8_t flag;
> flag ++;

Wo wird denn das je gesetzt & wieder zurückgesetzt ?

von Stefan F. (Gast)


Lesenswert?

Gehört die if Abfrage nicht innerhalb der while schleife?
1
while (1) 
2
{
3
    if(flag == 5)
4
    {
5
        ....
6
    }
7
}

von Ralf G. (ralg)


Lesenswert?

1
volatile uint8_t flag;

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.