TLC5940 am ATmega16

Gast #4105743
Lesenswert?

Hallo Leute,

ich versuche einen TLC5940 (LED-Treiber) an einem ATmega16 zu betreiben. 
Die Verdrahtung habe ich auf einem Steckbrett wie im Schaltplan 
angegeben vorgenommen.
Den Quellcode habe ich größtenteils von Demystifying the TLC5940 
(https://sites.google.com/site/artcfox/demystifying-the-tlc5940) 
übernommen. Dort wird ein ATmega328P verwendet, so dass ich folgende 
Anpassungen gemacht habe:
Für den Grundtakt des TLC wurde beim ATmega328P der CLKO-Pin verwendet, 
an dem der Prozessortakt abgegriffen werden kann. Der ATmega16 hat so 
einen Pin nicht, so dass ich stattdessen mittels eines als 
CTC-konfigurierten Timers mit Prescale 1 und dem Schwellwert 0 (ORC0 = 
0) am Pin OC0 (PB3) den halben Prozessortakt ausgegeben habe.
Alle 4096-TLC-Takte muss der TLC-Blank-Pin kurz auf HIGH gezogen werden, 
wozu ich den Timer2 ebenfalls im CTC-Modus verwendet habe. Dieser hat 
einen Prescaler von 1024 und einen Schwellwert von 7 (OCR2 = 7) -> alle 
8196 Prozessortakte = alle 4096 PB3-Takte.

Leider bleiben alle angeschlossenen LEDs aus. Lediglich wenn ich den 
Prozessor mit dem MKII über JTAG programmiere, leuchten die LEDs für ca. 
eine halbe Sekunde bevor sie dann wieder komplett ausgehen.
Wenn ich den Teil mit der DotCorrection auskommentire, dann sind einige 
LEDs ebenfalls an (die gleichen, die zuvor für eine halbe Sekunde an 
waren), aber egal welche Werte ich dem TLC übergebe, welche und wie 
stark die LEDs leuchten kann ich nicht beeinflussen. Hier mal die 
Funktionen, die die DotCorrection und die GrayScale-Werte setzen:
1
void TLC5940_ClockInDC(void) {
2
  setHigh(DCPRG_PORT, DCPRG_PIN);
3
  setHigh(VPRG_PORT, VPRG_PIN);
4
  for (dcData_t i = 0; i < dcDataSize; i++) {
5
    // Start transmission
6
    SPDR = dcData[i];
7
    // Wait for transmission complete
8
    while (!(SPSR & (1 << SPIF)));
9
    //pulse(SCLK_PORT, SCLK_PIN); // <-------- notwendig?
10
  }
11
  pulse(XLAT_PORT, XLAT_PIN);
12
}
13

14
ISR(TIMER2_COMP_vect) {
15
  static uint8_t xlatNeedsPulse = 0;
16
  setHigh(BLANK_PORT, BLANK_PIN);
17
  if (outputState(VPRG_PORT, VPRG_PIN)) {
18
    setLow(VPRG_PORT, VPRG_PIN);
19
    if (xlatNeedsPulse) {
20
      pulse(XLAT_PORT, XLAT_PIN);
21
      xlatNeedsPulse = 0;
22
    }
23
    pulse(SCLK_PORT, SCLK_PIN);
24
  } else if (xlatNeedsPulse) {
25
    pulse(XLAT_PORT, XLAT_PIN);
26
    xlatNeedsPulse = 0;
27
  }
28
  setLow(BLANK_PORT, BLANK_PIN);
29
  // Below this we have 4096 cycles to shift in the data for the next cycle
30
  for (gsData_t i = 0; i < gsDataSize; i++) {
31
    SPDR = gsData[i];
32
    while (!(SPSR & (1 << SPIF)));
33
    //pulse(SCLK_PORT, SCLK_PIN); // <-------- notwendig?
34
  }
35
  xlatNeedsPulse = 1;
36
}

Hat jmd von euch einen Idee, was ich falsch mache? Ein Oszilloskop habe 
ich leider nicht um die Signale oder deren Timing zu überwachen.

Gruß
Michi
Angehängte Dateien:
Gast #4107126
Lesenswert?

Hallo Frank,

danke für deine Antwort.
Mein Fehler war, dass ich bei der Initialisierung von GSCKL 
versehentlich
1
setOutput(GSCLK_PORT, GSCLK_PIN);
statt
1
setOutput(GSCLK_DDR, GSCLK_PIN);

gesetzt habe und dass ich (wahrscheinlich durch eine Fehlkonfiguration) 
den Baustein so überhitzt habe, dass er nicht mehr richtig funktioniert 
hat. Nachdem ich ihn ausgetauscht hab, funktioniert jetzt alles 
einwandfrei.

Gruß
Michi

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