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