Hallo zusammen,
ich versuche mich momentan mit dem Soft PWM aus dem Tutorial.
Mein Ziel ist es, eine LED Matrix mit "beliebiger" grösse (vorerst mal
8x8 Matrix) mit Soft PWM anzusteuern. Es sollen zufällige LEDs
abwechslungsweise langsam ein- und ausgeschaltet werden.
Auf der Basis des Beispielprogrammes unten habe ich ein fading alles
LEDs hinbekommen.
Jetzt wollte ich die dauer des fading sowie die maximale helligkeit
variieren können. Ich habe einiges probiert und musste feststellen, dass
ich wohl die ISR nicht ganz verstehe... kann mir jemand auf die sprünge
helfen?
was ich auch nicht verstehe, warum in der ISR die variable pwm_cnt auf 0
gesetzt wird, wenn (PWM_STEPS-1) erreicht wird
1 | if (pwm_cnt==(uint8_t)(PWM_STEPS-1))
|
2 | pwm_cnt=0;
|
3 | else
|
4 | pwm_cnt++;
|
was für ein sinn macht das ?
ebenfalls wird am anfang der ISR pwm_cnt=0; gesetzt, somit wird doch
obige abfrage immer auf das "else" ausweichen ?! Oder was verstehe ich
hier nicht richtig ?
danke schon im voraus !
1 | // Defines an den Controller und die Anwendung anpassen
|
2 |
|
3 | #define F_CPU 8000000L // Systemtakt in Hz
|
4 | #define F_PWM 100 // PWM-Frequenz in Hz
|
5 | #define PWM_STEPS 256 // PWM-Schritte pro Zyklus(1..256)
|
6 | #define PWM_PORT PORTD // Port für PWM
|
7 | #define PWM_DDR DDRD // Datenrichtungsregister für PWM
|
8 |
|
9 | // ab hier nichts ändern, wird alles berechnet
|
10 |
|
11 | #define T_PWM (F_CPU/(F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt
|
12 |
|
13 | #if (T_PWM<(93+5))
|
14 | #error T_PWM zu klein, F_CPU muss vergrösst werden oder F_PWM oder PWM_STEPS verkleinert werden
|
15 | #endif
|
16 |
|
17 | // includes
|
18 |
|
19 | #include <stdint.h>
|
20 | #include <string.h>
|
21 | #include <avr/io.h>
|
22 | #include <avr/interrupt.h>
|
23 |
|
24 | // globale Variablen
|
25 |
|
26 | volatile uint8_t pwm_setting[8];
|
27 |
|
28 | // Timer 1 Output COMPARE A Interrupt
|
29 |
|
30 | ISR(TIMER1_COMPA_vect) {
|
31 | static uint8_t pwm_cnt=0;
|
32 | uint8_t tmp=0;
|
33 |
|
34 | OCR1A += (uint16_t)T_PWM;
|
35 |
|
36 | if (pwm_setting[0] > pwm_cnt) tmp |= (1<<0);
|
37 | if (pwm_setting[1] > pwm_cnt) tmp |= (1<<1);
|
38 | if (pwm_setting[2] > pwm_cnt) tmp |= (1<<2);
|
39 | if (pwm_setting[3] > pwm_cnt) tmp |= (1<<3);
|
40 | if (pwm_setting[4] > pwm_cnt) tmp |= (1<<4);
|
41 | if (pwm_setting[5] > pwm_cnt) tmp |= (1<<5);
|
42 | if (pwm_setting[6] > pwm_cnt) tmp |= (1<<6);
|
43 | if (pwm_setting[7] > pwm_cnt) tmp |= (1<<7);
|
44 | PWM_PORT = tmp; // PWMs aktualisieren
|
45 | if (pwm_cnt==(uint8_t)(PWM_STEPS-1))
|
46 | pwm_cnt=0;
|
47 | else
|
48 | pwm_cnt++;
|
49 | }
|
50 | int main(void) {
|
51 | // PWM einstellen
|
52 | PWM_DDR = 0xFF; // Port als Ausgang
|
53 | // Timer 1 OCRA1, als variablem Timer nutzen
|
54 | TCCR1B = 1; // Timer läuft mit vollem Systemtakt
|
55 | TIMSK1 |= (1<<OCIE1A); // Interrupt freischalten
|
56 | sei(); // Interrupts gloabl einschalten
|
57 | return 0;
|
58 | }
|