Ich stelle hier mal ein kleines Program zum Ansteuern von WS2812B LED
Pixeln rein. Eine passende Lib ohne HAL konnte ich auf die schnelle
nicht finden, deshalb hier der 100ertste Aufguss.
Das ganze ist für STM32F103 bzw. STM32F3x3 (BluePill u.ä.).
Verwendet wird A8 als Ausgang, da der einmal 5V tauglich ist und zum
anderen nicht von den anderen UARTs,SPIs,I2Cs belegt ist. Bei mir gehen
die Pixel direkt am 3.3V Push/Pull Ausgang, bei Problemen kann man aber
auch den Ausgang als OpenDrain konfigurieren mit einem Widerstand gegen
+5V.
A8 bedingt Timer 1 Channel 1 und DMA1 Channel5. Die Ausgabe erfolgt
continuierlich mit 75µs Pause zwischen den Paketen und läuft komplett
ohne CPU und ohne Interrupts. Im TIM1 Update wird jeweil des nächste
Byte in das PWM Register TIM1->CCR1 geschrieben. Der DMA Teil läuft
cirkular durch, die nötigen Breaks werden durch eine entsprechende Anzal
0-Bytes realisiert.
Ein kurzes Testprogramm sieht so aus:
1 | #include <ws2812b.h>
|
2 |
|
3 | Ws2812<12> aWs; // 12 Pixel Länge
|
4 | void TestWs()
|
5 | {
|
6 | aWs.Init();
|
7 | aWs.SetDimmer(30);
|
8 | int dt=10;
|
9 | int n=0;
|
10 | while (1)
|
11 | {
|
12 | aWs.SetRgb(n,0,127,0);
|
13 | delay_ms(dt);
|
14 | aWs.SetRgb(n+1,127,0,0);
|
15 | delay_ms(dt);
|
16 | aWs.SetRgb(n+2,0,0,127);
|
17 | delay_ms(dt);
|
18 | aWs.SetRgb(n+3,80,80,80);
|
19 | delay_ms(dt);
|
20 | n++;
|
21 | if (n==12)
|
22 | n=0;
|
23 | }
|
24 | }
|
Andere Abhängigkeiten ausser den µC-Headern gibt es nicht.
Auf eine Doppelbufferung wurde verzichtet. Ich brauche das nicht für
Lichtspielereien, sondern nutze das zu sowas wie Akkulandestands Anzeige
o.ä. mit wenigen Pixeln.
https://www.amazon.de/ZHITING-Lichtstreifen-Treiberplatine-8-Kanal-integrierte-vollfarbgesteuerte-Entwicklungsplatine/dp/B08J2S5N8D/ref=sr_1_5?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&dchild=1&keywords=neopixel&qid=1617358391&s=software&sr=1-5