Hallo Ihr, ich versuche seit gestern ein Soft-PWM Programm nach Vorbild aus dem Artikel hier, auf meinem Atmega 328p mit 16MHz zum Laufen zu bringen. Vorerst sollte lediglich ein PWM Signal mit jeweils unterschiedlichem Duty Cycle an 3 Pins anliegen. Um zu sehen was an den Ausgängen passiert schließe ich dort testweise eine LED an. Da alte Programme einwandfrei laufen und auch die Fuses richtig gesetzt sind, liegt es mit 95 prozentiger Sicherheit an Codefehlern. Das Problem ist, dass an den Ausgängen zwar ein PWM Signal anliegt jedoch mit einer Frequenz im ein- bis zweistelligen Hertz Bereich. Das heißt etwa 100mal zu langsam. Ich hoffe Ihr findet meinen dämlichen Fehler wieder mal und helft mir aus der Patsche. Danke schonmal für die Mühe! Hier mal der Code:
1 | #define F_CPU 16000000UL
|
2 | |
3 | #define F_PWM 100 // PWM-Frequenz in Hz
|
4 | |
5 | #define PWM_STEPS 256UL // PWM-Schritte pro Zyklus(1..256)
|
6 | |
7 | #define PWM_PORT PORTD // Port für PWM
|
8 | #define PWM_DDR DDRD // Datenrichtungsregister für PWM
|
9 | |
10 | |
11 | #define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt
|
12 | |
13 | |
14 | #include <avr/io.h> |
15 | #include <avr/interrupt.h> |
16 | |
17 | volatile uint8_t red1=30; |
18 | volatile uint8_t green1=100; |
19 | volatile uint8_t blue1=200; |
20 | |
21 | void timer_init(){ |
22 | |
23 | //Timer 1 in CTC Mode with F_CPU
|
24 | TCCR1B |= (1<<WGM12) | (1<<CS10); |
25 | TIMSK1 |= (1<<OCIE1A); // Interrupt freischalten |
26 | OCR1A=T_PWM; |
27 | sei(); // Interrupts global einschalten |
28 | }
|
29 | |
30 | void io_init(){ |
31 | PWM_DDR = 0xff; |
32 | PWM_PORT=0; |
33 | }
|
34 | |
35 | |
36 | |
37 | ISR(TIMER1_COMPA_vect) { |
38 | static uint8_t pwm_cnt=0; |
39 | uint8_t tmp=0; |
40 | |
41 | OCR1A += (uint16_t)T_PWM; |
42 | |
43 | |
44 | if (red1 > pwm_cnt) tmp |= (1<<2); |
45 | if (green1 > pwm_cnt) tmp |= (1<<3); |
46 | if (blue1 > pwm_cnt) tmp |= (1<<4); |
47 | |
48 | PWM_PORT = tmp; // PWMs auf Port schreiben |
49 | |
50 | if (pwm_cnt==(uint8_t)(PWM_STEPS-1)) |
51 | pwm_cnt=0; |
52 | else
|
53 | pwm_cnt++; |
54 | |
55 | }
|
56 | |
57 | int main(void) |
58 | {
|
59 | io_init(); |
60 | timer_init(); |
61 | |
62 | while(1) |
63 | {
|
64 | |
65 | }
|
66 | |
67 | return 0; |
68 | }
|