Hi,
ich habe folgendes Problem. Ziel ist es, eine LED-Fading zu realisieren.
Klar habe ich die Artikel dazu gelesen. Mein Code führt dazu das die LED
ehr unkoordiniert flackert.
1 | #include <avr/io.h>
| 2 | #include <avr/interrupt.h>
| 3 | #include <stdint.h>
| 4 | #include <stdbool.h>
| 5 |
| 6 | #define LED_DDR (DDRD)
| 7 | #define LED_PORT (PORTD)
| 8 | #define LED (1<<3)
| 9 |
| 10 | static const uint16_t pwmtable_16[256] PROGMEM =
| 11 | {
| 12 | 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
| 13 | 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7,
| 14 | 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15,
| 15 | 15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
| 16 | 31, 32, 33, 35, 36, 38, 40, 41, 43, 45, 47, 49, 52, 54, 56, 59,
| 17 | 61, 64, 67, 70, 73, 76, 79, 83, 87, 91, 95, 99, 103, 108, 112,
| 18 | 117, 123, 128, 134, 140, 146, 152, 159, 166, 173, 181, 189, 197,
| 19 | 206, 215, 225, 235, 245, 256, 267, 279, 292, 304, 318, 332, 347,
| 20 | 362, 378, 395, 412, 431, 450, 470, 490, 512, 535, 558, 583, 609,
| 21 | 636, 664, 693, 724, 756, 790, 825, 861, 899, 939, 981, 1024, 1069,
| 22 | 1117, 1166, 1218, 1272, 1328, 1387, 1448, 1512, 1579, 1649, 1722,
| 23 | 1798, 1878, 1961, 2048, 2139, 2233, 2332, 2435, 2543, 2656, 2773,
| 24 | 2896, 3025, 3158, 3298, 3444, 3597, 3756, 3922, 4096, 4277, 4467,
| 25 | 4664, 4871, 5087, 5312, 5547, 5793, 6049, 6317, 6596, 6889, 7194,
| 26 | 7512, 7845, 8192, 8555, 8933, 9329, 9742, 10173, 10624, 11094,
| 27 | 11585, 12098, 12634, 13193, 13777, 14387, 15024, 15689, 16384,
| 28 | 17109, 17867, 18658, 19484, 20346, 21247, 22188, 23170, 24196,
| 29 | 25267, 26386, 27554, 28774, 30048, 31378, 32768, 34218, 35733,
| 30 | 37315, 38967, 40693, 42494, 44376, 46340, 48392, 50534, 52772,
| 31 | 55108, 57548, 60096, 62757, 65535
| 32 | };
| 33 |
| 34 |
| 35 | void setup()
| 36 | {
| 37 | //Port
| 38 | LED_DDR |= LED;
| 39 | LED_PORT |= LED;
| 40 | //Timer
| 41 | TIMSK1 = ((1<<OCIE1A) | (1<<TOIE1));
| 42 | TCCR1B |= (1<<CS10);
| 43 | //Interrupt
| 44 | sei();
| 45 | }
| 46 |
| 47 | void loop(void)
| 48 | {
| 49 | static uint8_t u8I = 0;
| 50 | OCR1A = pwmtable_16[u8I++];
| 51 | delay(400);
| 52 | }
| 53 |
| 54 | ISR(TIMER1_COMPA_vect)
| 55 | {
| 56 | LED_PORT |= LED; // switch led off
| 57 | }
| 58 |
| 59 | ISR(TIMER1_OVF_vect)
| 60 | {
| 61 | LED_PORT &= ~LED; // switch led on
| 62 | }
|
Ich habe es auch mit for-Schleife in der loop-Funktion probiert, was
ebenso nicht funktioniert. Was allerdings funktioniert, wenn ich das
Fading manuell mache, also wie folgend.
1 | void loop(void)
| 2 | {
| 3 | uint16_t u16Delay = 400;
| 4 |
| 5 | OCR1A = pwmtable_16[1];
| 6 | delay(u16Delay);
| 7 | OCR1A = pwmtable_16[2];
| 8 | delay(u16Delay);
| 9 | OCR1A = pwmtable_16[3];
| 10 | delay(u16Delay);
| 11 | OCR1A = pwmtable_16[4];
| 12 |
| 13 | // Und so weiter
| 14 | }
|
Für mich ist das Verhalten rätselhaft. Als wenn die loop nicht korrekt
Kompiliert wird.
@Tim S. (timer)
>ich habe folgendes Problem. Ziel ist es, eine LED-Fading zu realisieren.
>Klar habe ich die Artikel dazu gelesen. Mein Code führt dazu das die LED
>ehr unkoordiniert flackert.
Hmm. Was hindert dich daran, einfach mal de Originalquelltext
unverändert auf deinen AVR zu laden? Das minimiert die Fehlerquellen.
> TIMSK1 = ((1<<OCIE1A) | (1<<TOIE1));
> TCCR1B |= (1<<CS10);
Wo wird OCRx freigeschaltet? COMxy Bits.
>ISR(TIMER1_COMPA_vect)
>{
> LED_PORT |= LED; // switch led off
>}
Das LED-Fading im Artikel benutzt die Hardware-PWM, was vor allem bei 16
Bit PWM auch gar nicht ander geht. Du versuchst hier ein Software-PWM.
>Ich habe es auch mit for-Schleife in der loop-Funktion probiert, was
>ebenso nicht funktioniert. Was allerdings funktioniert, wenn ich das
>Fading manuell mache, also wie folgend.
Glaub ich nicht so recht, das ist eher ein Dreckeffekt, der dir ein
funktionierendes Programm vorgaukelt.
>Für mich ist das Verhalten rätselhaft. Als wenn die loop nicht korrekt
>Kompiliert wird.
;-)
Falk B. schrieb:
>
> Hmm. Was hindert dich daran, einfach mal de Originalquelltext
> unverändert auf deinen AVR zu laden? Das minimiert die Fehlerquellen.
Weil ich Soft-PWM benötige, der Fading-Artikel verwendet Hardware-PWM.
Der Code aus dem Soft-PWM Artikel realisiert PWM auf nen ganzen Port,
ich brauche ihn für einen speziellen Pin.
> Wo wird OCRx freigeschaltet? COMxy Bits.
Wegen Soft-PWM brauche ich die Pins nicht.
> Das LED-Fading im Artikel benutzt die Hardware-PWM, was vor allem bei 16
> Bit PWM auch gar nicht ander geht. Du versuchst hier ein Software-PWM.
Ja, das versuche ich.
> Glaub ich nicht so recht, das ist eher ein Dreckeffekt, der dir ein
> funktionierendes Programm vorgaukelt.
Dreckeffekt? Warum sollte es nicht funktionieren?
@ Tim S. (timer)
>Weil ich Soft-PWM benötige, der Fading-Artikel verwendet Hardware-PWM.
>Der Code aus dem Soft-PWM Artikel realisiert PWM auf nen ganzen Port,
>ich brauche ihn für einen speziellen Pin.
Leg lieber einen Draht auf deiner Platine zum passenden PWM-Pin, das
geht deutlich schneller und ist einfacher.
>> Das LED-Fading im Artikel benutzt die Hardware-PWM, was vor allem bei 16
>> Bit PWM auch gar nicht ander geht. Du versuchst hier ein Software-PWM.
>Ja, das versuche ich.
Hast du schon mal einen Gedanken daran verschwendet, warm man in
bestimmten Situationen KEIN Software-PWM verwenden will/kann. Und wo die
Grenzen von Soft-PWM liegen?
Hi
1 | void loop(void)
| 2 | {
| 3 | static uint8_t u8I = 0;
| 4 | OCR1A = pwmtable_16[u8I++];
| 5 | delay(400);
| 6 | }
|
Wenn ich den Code richtig verstehe, wird die Variabel u8I auf 0 gesetzt
und danach der Wert 1 (u8I + 1, oder Wert 0 und u8I um Eins erhöht) des
Array in das Match-A-Register des Timer 1 geladen.
Und Das immer wieder - da ich das '=0' so interpretiere, daß der
Variabel JEDES MAL der Wert 0 zugeteilt wird.
Wenn NICHT, also diese Zuweisung nur 1x ausgeführt wird - gehört die
Zeile eher in den Init-Bereich.
MfG
Falk B. schrieb:
> Leg lieber einen Draht auf deiner Platine zum passenden PWM-Pin, das
> geht deutlich schneller und ist einfacher.
Die sind alle schon belegt.
> Hast du schon mal einen Gedanken daran verschwendet, warm man in
> bestimmten Situationen KEIN Software-PWM verwenden will/kann. Und wo die
> Grenzen von Soft-PWM liegen?
Verschwendet ist hier vielleicht der richtige Ausdruck. Eine LED zu
dimmen sollte wohl kein Problem darstellen. Zu mal es ja bei manueller
Programmierung funktioniert.
Patrick J. schrieb:
> Wenn ich den Code richtig verstehe, wird die Variabel u8I auf 0 gesetzt
> und danach der Wert 1 (u8I + 1, oder Wert 0 und u8I um Eins erhöht) des
> Array in das Match-A-Register des Timer 1 geladen.
> Und Das immer wieder - da ich das '=0' so interpretiere, daß der
> Variabel JEDES MAL der Wert 0 zugeteilt wird.
>
> Wenn NICHT, also diese Zuweisung nur 1x ausgeführt wird - gehört die
> Zeile eher in den Init-Bereich.
>
> MfG
Die Variable ist statisch, dass heißt, sie wird nur einmalig
initialisiert. Ich kann sie natürlich auch global deklarieren und dann
im setup-Bereich initialisieren. Kommt aber auf's gleiche heraus.
@ Tim S. (timer)
>Verschwendet ist hier vielleicht der richtige Ausdruck. Eine LED zu
>dimmen sollte wohl kein Problem darstellen. Zu mal es ja bei manueller
>Programmierung funktioniert.
Schon mal nachgerechnet, wie oft deine beiden ISRs aufgerufen werden?
Patrick J. schrieb:
> Wenn NICHT, also diese Zuweisung nur 1x ausgeführt wird - gehört die
> Zeile eher in den Init-Bereich.
Das ist keine Zuweisung, sondern eine Initialisierung. Und da die
Variable static ist, wird sie nur einmal erzeugt und damit auch nur
einmal initialisiert.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|