Forum: Mikrocontroller und Digitale Elektronik Fading in Schleife


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Tim S. (timer)


Bewertung
0 lesenswert
nicht 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.

von Falk B. (falk)


Bewertung
0 lesenswert
nicht 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.

;-)

von Tim S. (timer)


Bewertung
0 lesenswert
nicht 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?

von Falk B. (falk)


Bewertung
0 lesenswert
nicht 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?

: Bearbeitet durch User
von Patrick J. (ho-bit-hun-ter)


Bewertung
0 lesenswert
nicht 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

von Tim S. (timer)


Bewertung
0 lesenswert
nicht 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.

von Tim S. (timer)


Bewertung
0 lesenswert
nicht 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.

von Falk B. (falk)


Bewertung
0 lesenswert
nicht lesenswert
@ 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?

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.