Forum: Mikrocontroller und Digitale Elektronik STM32F4Discovery und TLC5940


von Mario S. (masp)


Lesenswert?

Hallo zusammen,

ich versuche aktuell einen TLC5940 (16 Kanal LED-Treiber mit 12 Bit PWM) 
an einem STM32F407VG (STM32F4Discovery-Board) zur laufen zu bekommen. 
Der TLC5940 ist grundsätzlich folgend zu betreiben:

1. Er braucht einen externen Takt für die PWM (GSCLK). Alle 4096 Ticks 
muss die PWM zurückgesetzt werden (BLANK).

2. Die PWM-Daten erhält er in 192 Bit-Paketen 16 * 12 Bit 
(PWM-Auflösung) über ein SPI-ähnliches Interface (nur SCLK, SIN, kein 
CS). Die Daten werden nach der Übertragung mit einem XLAT Pulse 
übernommen.

Das habe ich nun folgend bisher gelöst:

1. Der STM32 erzeugt eine Clock Frequenz über die eigene PWM. Dieses 
Signal geht direkt an GSCLK

2. Per Timer wird in gleicher Freuquenz mit einem Counter von 4096 ein 
ISR erzeugt, der die neuen Daten (so denn neue vorliegen) zum TLC5940 
überträgt.

Das funktioniert auch schon sehr gut bis zu einer Frequenz von 21 Mhz 
GSCLK. Mehr wird über Breadboard und Jumpwires wohl auch nicht gehen, da 
muss erst die Platine fertig werden.

Allerdings habe ich bisher noch keine Möglichkeit gefunden, die 
PWM-Daten per SPI oder USART an den TLC5940 zu senden, daher erfologt 
dies aktuell noch per Bit-Bang in der Interrupt-Routine, was natürlich 
nicht besonder effizient ist. Ein SPI per DMA wäre mir natürlich 
deutlich lieber. Das funktioniert aber irgendwie nicht.

Folgende Initialisierung nutze ich bisher:
1
// Use SPI2 for TLC5940 Communication (Max 21 Mhz)
2
#define SPI2_MOSI_PORT                          GPIOB // Alternate(5)
3
#define SPI2_MOSI_PIN                           15
4
#define SPI2_SCLK_PORT                          GPIOB // Alternate(5)
5
#define SPI2_SCLK_PIN                           13
6
#define SPI2_CS_PORT                            GPIOB // Alternate(5)
7
#define SPI2_CS_PIN                             12 // Not Connected
8
9
.
10
.
11
.
12
static const SPIConfig spi2cfg = {
13
  NULL,
14
  SPI2_CS_PORT,
15
  SPI2_CS_PIN,
16
  0 // Full 21 MHz-Speed
17
};
18
.
19
.
20
.
21
palSetPadMode(SPI2_SCLK_PORT, SPI2_SCLK_PIN, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_MID2);
22
palSetPadMode(SPI2_MOSI_PORT, SPI2_MOSI_PIN, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_MID2);
23
palSetPadMode(SPI2_CS_PORT, SPI2_CS_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_MID2);
24
palSetPad(SPI2_CS_PORT, SPI2_CS_PIN);
25
spiAcquireBus(&SPID2);              /* Acquire ownership of the bus.    */
26
spiStart(&SPID2, &spi2cfg);           /* Setup transfer parameters.       */

In der ISR nutze ich folgenden Code
1
spiSelectI(&SPID2);                  /* Slave Select assertion.          */
2
spiStartSendI(&SPID2, gsDataSize, gsData);
3
spiUnselectI(&SPID2);                /* Slave Select de-assertion.       */

Wie man sieht nutze ich ChibiOS. Das kann ich als Fehlerquelle aber 
ausschließen, da SPI mit anderen Komponenten problemlos funktioniert.

Der TLC5940 nutzt allerdings kein CS. Bespiele die es für den TLC5940 
für den AVR gibt, funktionieren mit SPI aber wohl. Ich habe es auch 
schon mit SPI_CR1_CPOL und SPI_CR1_CPHA in allen Kombinantionen 
versucht. Kein Erfolg. Ich habe es natürliche auch bereits mit deutlich 
niedrigeren Frequenzen bis 384Khz SPI ausprobiert, aber nichts klappt. 
Auch die GPIO_Speed habe ich variiert mit MID1, MID2 oder HIGHEST. Aber 
auch das ändert nichts. Der TLC5940 verträgt laut Datenblatt bis 30Mhz 
und das klappt per Bit-Banging ja auch.

Hat jemand ggf. dieses Problem auch oder hat andere SPI-Probleme beim 
STM32F407VG identifiziert, die mir hierbei helfen könnten? Das 
spiStartSendI nutze ich, da im ISR natürlich keine CallBacks möchlich 
sind, die bei spiStartSend() aufgerufen würden.

Alternativ könnte man ggf. ein Bit-Bangig direkt per DMA machen, aber 
dafür fehlt mir die Erfahrung mit dem STM32. Gibt es hierfür evtl. 
Beispiel? Bisher habe nicht nur eine VGA Ansteuerung per Bit-Banging 
gefunden, die habe ich aber noch nicht ganz verstanden.

Gruß
Mario

von Elmar B. (sedlab)


Lesenswert?

Hallo,

leider kann ich bei diesem Problem nicht helfen, mich würde allerdings 
interessieren wo du den TLC9540 gekauft hast. Bisher habe ich nur den 
Vertrieb über USA und China gefunden, wobei allerdings eine 
Mindestbestellmenge von 130 Stück verlangt wird. Gibt es alternative 
Anbieter?

lg

von Mario S. (masp)


Lesenswert?

Hallo Elmar,

ich habe den TLC5940 auch nur bei eBay gefunden. Dort gibt es ihn für 
ca. 6 EUR/Stück zzgl. Versand.

Inzwischen habe ich die Kommunikation per SPI verworfen und steuere den 
TLC nun doch per Bit-Bang an. 6 TLC5940 mit 28Mhz lassen sich von 
stm32f407vg noch ohne Probleme ansteuern. Da bleibt auch noch genug 
Rechenzeit für eine SPI-Kommunikation zu einem Master übrig (Raspberry 
PI).

Gruß
Mario

von Gebhard R. (Firma: Raich Gerätebau & Entwicklung) (geb)


Lesenswert?

Schon mal mit dem Oszi die SPI-Pins angeschaut?

Grüsse

von Falk B. (falk)


Lesenswert?

@Allerdings habe ich bisher noch keine Möglichkeit gefunden, die
>PWM-Daten per SPI oder USART an den TLC5940 zu senden,

Warum nicht? Weil man die Bit ein ein wenig umsortieren muss? Kein 
Problem mit Bitmanipulation.

http://www.mikrocontroller.net/articles/Bitmanipulation#Siehe_auch

>Der TLC5940 nutzt allerdings kein CS.

Doch, nur dass es nicht CS heißt sondern LATCH. Wirkt aber im Prinzip 
genau so.

>für den AVR gibt, funktionieren mit SPI aber wohl. Ich habe es auch
>schon mit SPI_CR1_CPOL und SPI_CR1_CPHA in allen Kombinantionen
>versucht. Kein Erfolg.

Mal mit dem Oszi genmessen?

von Mario S. (masp)


Lesenswert?

Hallo Falk,

sicher hast du recht, das es per SPI per DMA auch vom stm32 aus gehen 
sollte, aber da ich leider kein Oszi, war ich mit meinen 
Analysemöglichkeiten ziemlich am Ende. Letztlich müssen die Daten für GS 
und DC nur seriell an einen PIN im Takt der an GSCLK anliegt und nach 
192 muß man die Daten "einlatchen". Da ich 6 TLC ansteuern möchte, habe 
ich mich aus Timing-gründen entschieden diese parallel mit 6 getrennten 
Datenleitungen per Bit-Bang zu bedienen und nicht seriell 
hintereinandergeschlatet, was der TLC auch unterstützen würde. 6 SPI 
hätte ich ohnehin nicht verfügbar.

Mein Problem ist also erstmal gelöst.

Danke
Mario

von Martini (Gast)


Lesenswert?

Hallo,

sollte es nach 6 Monaten noch jemanden interessieren, kann er sich hier 
einlesen:

https://sites.google.com/site/artcfox/demystifying-the-tlc5940

Gruß,

Marcus

von Ben W. (ben_w)


Lesenswert?

auch wenn der Beitrag schon etwas älter ist ...

stehe gerade vor dem gleichen Problem
per Bitbang funktioniert alles
sobald ich hardware SPI + DMA einsetze geht es nicht mehr.

Es hat den Anschein das irgendwo Bit(s) zu viel oder zu wenig in das 
Schieberegister des TLC5940 hineingetaktet werden.
Aber ich finde einfach nicht den Fehler.
Habe auch alle Variationen mit SPI_CR1_CPOL und SPI_CR1_CPHA ausprobiert 
und den Takt auf 800 kHz runtergesetzt. Hilft leider alles nichts :(

Hat jemand zufällig ein Beispiel Code mit dem STM32F4 + SPI + TLC5940 
funktioniert?

von Tappan (Gast)


Lesenswert?

Hi, hatte eigentlich ebenfalls vor den TLC über SPI mit einem STM 
anzusteuern, nach den ganzen Negativerfahrungen werde ich wohl doch 
einen AVR nehmen...

Versuch doch mal nur Einsen reinzuschieben und gucke ob es dann geht, 
dann den Fehler versuchen weiter einzugrenzen.

von Gerhard W. (dd4da) Flattr this


Lesenswert?

. 6 SPI hätte ich ohnehin nicht verfügbar.
>
> Mein Problem ist also erstmal gelöst.

Ok, ich wusste gar nicht dass der SPI-Bus "Single-Ended" ist. Wenn 
gleich der Artikel älter, und das problem scheinbar gelöst wurde so 
sollte ergänzt werden dass der SPI ein Bus ist und man mit CS den 
anzusprechenden Chip auswählt.
Warum man in diesem Fall nun unbedingt den DMA zur Übertragung zum SPI 
nutzen will, öffnet sich mir auch nicht wirklich. In anbetracht der 
vorhandenen Microcontroller-Performance sehe ich eigentlich keinen 
wirklichen Sinn darin. Einfache Aufgaben lassen sich sicherlich auch 
durch komplexe Lösungen erledigen - ob es ein angestrebtes Ziel sein 
sollte kann ich mir jedoch nur bedingt vorstellen.

Greez

von Falk B. (falk)


Lesenswert?

@ Gerhard Wesser (dd4da)

>Ok, ich wusste gar nicht dass der SPI-Bus "Single-Ended" ist. Wenn

Du meinst eine Punkt zu Punkt Verbindung.

>sollte ergänzt werden dass der SPI ein Bus ist und man mit CS den
>anzusprechenden Chip auswählt.

Genau. Ausserdem kann man die TLC5940 kaskadieren und als eine einzigen 
SPI-Slave ansprechen.

>Warum man in diesem Fall nun unbedingt den DMA zur Übertragung zum SPI
>nutzen will, öffnet sich mir auch nicht wirklich. In anbetracht der
>vorhandenen Microcontroller-Performance sehe ich eigentlich keinen
>wirklichen Sinn darin.

Nö, aber wenn es der Prozesosor hergibt, warum nicht. Einen DMA 
COntroller richtig zu konfigurieren und nutzen sollte doch nicht das 
Riesenproblem sein. Gerade wo doch AVRs out und ARMs in sind ;-)

von Falk B. (falk)


Lesenswert?

@ Ben W. (ben_w)

>Es hat den Anschein das irgendwo Bit(s) zu viel oder zu wenig in das
>Schieberegister des TLC5940 hineingetaktet werden.
>Aber ich finde einfach nicht den Fehler.

Dann betreibe Fehlersuche mit einem Oszilloskop.

von dd4da (Gast)


Lesenswert?

Falk Brunner schrieb:
> Nö, aber wenn es der Prozesosor hergibt, warum nicht. Einen DMA
>
> COntroller richtig zu konfigurieren und nutzen sollte doch nicht das
>
> Riesenproblem sein. Gerade wo doch AVRs out und ARMs in sind ;-)

Ob AVR's out sind und ARM's in will ich nicht beurteilen wollen. Ich 
gebe zu bedenken dass  ein AVR mit deutlich weniger Aufwand zu benutzen 
ist. Eine MPU alleine auf ein Lochraster gestopft und etwas Code kann 
schon zu erstaunlichen Lösungen führen. Beim ARM geht's in der Regel 
ohne Vorbereitung nicht "mal eben" - wenn wir mal von den vielen 
preiswerten China-Boards absehen. SMD hat sicherlich seinen Charme aber 
das erkauft man sich eben durch die Notwendigkeit einer Leiterkarte. Mit 
Pin-Abständen von 200mil ist mit "Selbermachen" wohl auch Ende. Ich 
glaube dass ein AVR a la xMega schon gut qualm machen kann. Für viele 
Spielereianwendungen reichen die in der Regel aus. Wenn sie allerdings 
ein 320x240 Pixel TFT bedienen müssen, muss man schon sehr auf den 
verwendeten Display -Controller achten sonst wird's sehr langsam. Es 
kommt halt immer auf die Anwendung an. Einen Hinweis noch zur Peripherie 
- die Auswahl für 3.3V Schnittstellenbauteile ist arg begrenzt und 
ebenfalls häufig nur SMD (a la SOT usw) verfügbar. Das macht der 
Spontanität auch einige Probleme. In 5 V Technik gibt es häufig noch DIP 
die man mal auf ein Brett stecken kann.
Nun mag man einwenden dass der Cortex von ST (STM32)und einige andere 
einen 5V toleranten I/O haben - aber ich muss die 5V und die 3.3V 
bereitstellen und das bedeutet eben auch Mehraufwand. Man sollte schon 
gute Gründe haben einen Cortex verwenden zu wollen. Nur mal so eben ist 
darin auch nicht eingearbeitet. Erfreulich finde ich es dass die JTAG's 
für den ARM sehr preiswert ist, was man weder von ATMEL noch von anderen 
behaupten kann. Ich benutze einen J-LINK EDU und der kostete rund €50.- 
und keine 250 und noch mehr - wie es bei Atmel oder anderen der Fall 
ist. Wenns noch preiswerter sein muss kann man den OpenOCD bauen. 
Scheint wohl ARM Politik zu sein.
Summa Sumarum - ich benutze sowohl den AVR(8BIT) als auch den Cortex - 
eben da wo es nötig ist den einen oder anderen Controller.
Greetz

von dd4da (Gast)


Lesenswert?

Falk Brunner schrieb:
> Du meinst eine Punkt zu Punkt Verbindung.

Japp

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.