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 | }
|