Fading in Schleife

OP #4889913
Lesenswert?

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.
#4889943
Lesenswert?

@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.

;-)
OP #4889978
Lesenswert?

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?
#4889997
Lesenswert?

@ 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?
#4890007
Lesenswert?

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
OP #4890012
Lesenswert?

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.
OP #4890016
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren