-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreadme.txt
419 lines (282 loc) · 15 KB
/
readme.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
Softwaremodul ws2812.c / ws2812.h
____________________________________________________________________________________________
Text und Software von R. Seelig
Inhaltsverzeichnis:
- Vorwort
- WS2812b Leuchtdioden
- Make
- WS2812b Header
- Funktionen von WS2812b
. rgbfromvalue
. rgbfromega
. ws_reset
. ws_showarray
. ws_clrarray
. ws_setrgbcol
. ws_setegacol
. ws_blendup_left
. ws_blendup_right
. ws_buffer_rl
. ws_buffer_rr
_______________________________________________
Vorwort
_______________________________________________
Seit geraumer Zeit schon gibt es Leuchtdioden mit "integriertem seriellen Controller". Diese
weerden oft fuer sehr kleines Geld (und absolut haeufig auch aus China auf EBAY) angeboten.
Genausooft (und noch guenstiger) werden Microcontroller der Familie STM8S angeboten und
der zweitpreiswerteste ist ein STM8S103F3P6 (auf EBAY werden 2 Stueck Minimumboards mit
dieser MCU fuer ca. 1,40 Euro angeboten, eigentlich unglaublich.
Leider ist die Unterstuetzung fuer diese MCU im Netz verglichen mit AVR und STM32 relativ
duerftig.
Auch freie Compiler hierfuer sind fast nicht verfuegbar und ausser dem SDCC habe ich
keinen freien (zumindest nicht limitierten) Compiler hierfuer gefunden. Von Cosmic gibt
es zwar einen "no limits compiler" aber ich habe nirgendwo einen Compiler fuer Linux auf
deren Seite entdeckt und so programmiere ich den STM8S eben mit SDCC.
Die Verwendung des Softwaremoduls kann somit mit:
Compiler : SDCC (ab Version 3.5.0)
MCU : STM8S103F3P6
Taktfrequenz MCU : 16MHz
LEDs : WS2812b
Betriebssystem : Linux
IDE : Make
betrieben werden. Eine IDE ist nicht zwingend notwendig, die Software wird mithilfe eines
Makefiles generiert.
_______________________________________________
WS2812b Leuchtdioden
_______________________________________________
WS2812b LEDs sind Vollfarb-LEDs (gruen / rot / blau) und besitzen einen "integrierten
seriellen Controller". Deren Funktionsweise ist in der Theorie relativ einfach (das
Programmieren fand ich dann doch relativ kniffelig).
Mittels einer einzigen Datenleitung empfaengt innerhalb einer Leuchtdiodenreihe die erste
LED Informationen. Diese sind 3 Bytes, jeweils eines fuer den Farbanteil von gruen, rot
und blau. Treffen nach diesen 3 Bytes weitere Bytes ein, werden die empfangenen Bytes
an den Ausgang der LED geschoben und einer weiteren nachgeschalteten LED uebergeben.
Reist der Datenstrom fuer eine gewisse Zeit ab (in der Regel betraegt diese Zeit
50 uSekunden) wird ein neuer Datenframe als Frame fuer die erste LED gewertet.
Eine WS2812b Leuchtdiode hat somit 4 Anschluesse: +Vcc, GND, Data_in und Data_out.
Beispiel: LED-Strang mit 4 LEDs
+Vcc
o------------+--------------+---------------+--------------+---------
|Vcc |Vcc |Vcc |Vcc
| | | |
Data +----+----+ +----+----+ +----+----+ +----+----+
o-------| in out |----| in out |-----| in out |----| in out |----
+----+----+ +----+----+ +----+----+ +----+----+
| | | |
GND GND| GND| GND| GND|
o------------+--------------+---------------+--------------+---------
In welcher Form liegen die Daten fuer WS2812 Leuchtdioden vor?
Es ist ein relativ einfaches Protokoll, welches jedoch recht sehr zeitkritisch ist.
Fuer ein Byte muessen 8 Bits uebertragen werden. Nachdem am Data-Input fuer min.
50 uSekunden ein Lo-Signal angelegt wird, beginnt die Datenuebertragung mit der ersten
Lo-Hi Flanke.
Ein Datenbit wird innerhalb einer Zeitspanne von 1,25 uSekunden uebertragen. Betraegt
die Pulsdauer des Signals 350 nSekunden (n= nano !!!) und 900 nSekunden die Pausedauer,
so wertet die WS2812 dieses als eingehende 0.
Betraegt die Pulsdauer 900nS und die Pausedauer 350nS, wird dieses als eingehende 1
gewertet.
Die Informationen werden in die LED in der Folge: gruen, rot und blau und die einzelnen
Bits mit der hoeheren Wertigkeit uebertragen. 3 Byte zu je 8 Bit benoetigen somit 24
Impulse (mit dem oben beschriebenen Timing).
Dieses Timing mit einem STM8S einzuhalten ist nicht ganz einfach und aus diesem Grund
wurde dieses Softwaremodul fuer einen mit 16 MHz betriebenen STM8 geschrieben.
Der Teil, der fuer den Datenstrom in die erste LED zustaendig ist, wurde mittels Bit-
banging in Assembler kodiert.
Das vorliegende ZIP-Archiv, zu dem diese Readme Datei gehoert, enthaellt alle Dateien,
die zum einfachen Uebersetzen des Demoprogrammes notwendig sind (ein installierter
SDCC Compiler wird vorausgesetzt).
_______________________________________________
Make
_______________________________________________
Bei der Programmierung hat es sich mehr oder weniger durchgesetzt, eine Uebersetzung
eines Quellprogramms die Steuerung der Uebersetzung einer sogenannten Make Datei zu
ueberlassen. Auf Betriebssystemebene wird auf einer Kommandozeile
make
in dem Ordner aufgerufen, in dem sich das Quellprogramm befindet. Selbst bei Be-
nutzung einer IDE wird dieses einem Make ueberlassen, welches jedoch haeufig in die
IDE integriert ist und die Makedatei aus Projekteinstelldaten erzeugt wird. Ueber-
sichtlicher finde ich jedoch, wenn die Makedatei im Text vorliegt um entsprechend
direkt mittels Texteingaben die Programmgenerierung steuern zu koennen.
Zu diesem Zwecke wurde hier Make in 2 Dateien aufgeteilt (case sensitiv):
- Makefile
- makefile.mk
Das Makefile ist sehr einfach gestaltet und an sich selbsterklaerend. Hier koennen
Angaben gemacht werden, welche Programmmodule zum Hauptprogramm hinzugefuegt werden
sollen, sowie die Pfade, in denen diese Module liegen koennen.
Im Vorliegenden Falle gibt es fuer einen Upload in die MCU zwei Moeglichkeiten, zum
einen mit der Verwendung eines STLINK v2 oder ueber einen selbst geschriebenen
Bootloader.
FLASHERPROG = 1
verwendet einen Bootloader, der an /dev/ttyUSB0 angeschlossen sein muss,
FLASHERPROG = 0
verwendet einen STLINK v2.
Weitere Sourcesoftware kann mittels
SRCS += nocheinedatei.rel
hinzugefuegt werden. Zu beachten, dass es hierfuer eine Datei Namens nocheinedatei.c
in den angegebenen Suchpfaden geben muss. Diese wird zu nocheinedatei.rel uebersetzt.
Makefile inkludiert eine weitere Datei: makefile.mk. Diese wertet die Benutzer-
angaben aus und generiert das Programm im Intel Hex-Format. Innerhalb dieser inkludierten
Datei werden Quelltexte uebersetzt und zu einem Gesamtprogramm zusammengelinkt.
_______________________________________________
WS2812b Header
_______________________________________________
ws2812b.h
---------
Angaben, die innerhalb ws2812b.h gemacht werden muessen:
Unter - ledanz - muss angegeben sein, wieviele Leuchtdioden eine
Leuchtdiodenreihe besitzt
Ausserdem muss angegeben sein, auf welchem Anschlusspin die Daten fuer
die WS2812b Leuchtdionden ausgegeben werden.
Hier sind die moeglichen Ports schon aufgefuehrt und auskommentiert.
Standardmaessig erfolgt die Datenausgabe auf
PD4
Soll das geaendert werden, muss der entsprechende Port entkommentiert werden
und der Pinanschluss unter gpio_pin angegeben werden.
Bsp.:
Soll die Ausgabe auf PB5 erfolgen, so sind im Header anzugeben:
#define ws_portb
#define gpio_pin 5
Strukturen, Variable und Funktionen von WS2812b
-----------------------------------------------
Das Array - ledbuffer -
Dieses Array nimmt die RGB-Werte fuer jede einzelene Leuchtdiod im Strang auf,
welche mittels - ws_showarray - ausgegeben werden kann.
Das Array - egapalette - beinhaltet 2 x 16 Farben die den "alten" Farben einer
EGA Grafikkarte (und den 16 Standardfarben unter Windows) entsprechen. Jede Farbe
benoetigt 3 Bytes (je eines fuer rot, gruen und blau). Die unteren 16 Farben sind
die Farben in "dunkel", die oberen 16 Farben sind dieselben Farben mit voller
Leuchtstaerke
Funktionen von WS2812b
________________________________________________________________________________________
rgbfromvalue
--------------------------------------------
void rgbfromvalue(uint8_t r, uint8_t g, uint8_t b, struct colvalue *f);
beschreibt eine struct Variable auf die *f zeigt mit einem RGB Farbwert.
Uebergabe:
r,g,b : RGB - Farbwert
*f : Zeiger auf die zu beschreibende
struct Variable
rgbfromega
--------------------------------------------
void rgbfromega(uint8_t eganr, struct colvalue *f);
beschreibt eine struct Variable auf die *f zeigt mit einem Farbwert, der aus der
EGA-Palette entnommen wird
Uebergabe:
nr : Farbeintrag der EGA-Palette
*f : Zeiger auf die zu beschreibende
struct Variable
ws_reset
--------------------------------------------
void ws_reset(void);
setzt die Leuchtdiodenreihe (fuer einen ncahfolgenden Datentransfer
zu den Leuchtdioden) zurueck
ws_showarray
--------------------------------------------
void ws_showarray(uint8_t *ptr, int anz)
(leider) in Maschinensprache, weil ich keinen anderen Weg gefunden habe, mittels
SDCC 350 Nanosekundenimpulse zu erzeugen.
Der SDCC legt seine Parameter auf den Stack in der Reihenfolge von hinten nach
vorne ab, hier also:
anz (2 Byte), *ptr (2 Byte), Ruecksprungadresse (2 Byte)
In wiefern andere Compiler den Stack belegen weiss ich in Ermangelung eines
anderen Compilers nicht und von daher wird diese Funktion wohl nur mit SDCC
(Version 3.5 oder hoeher sofern sich am Stackmanagment nichts aendert)
funktionieren.
Uebergabe:
*ptr : Zeiger auf ein Array, das angezeigt
werden soll
anz : Anzahl der anzuzeigenden LED's
ws_clrarray
--------------------------------------------
void ws_clrarray(uint8_t *ptr, int anz)
loescht ein LED Anzeigearray
Parameter:
*ptr : Zeiger auf ein Array, das
geloescht werden soll
anz : Anzahl der LEDs, die angezeigt
werden sollen
ws_setrgbcol
--------------------------------------------
void ws_setrgbcol(uint8_t *ptr, uint16_t nr, struct colvalue *f)
setzt den Farbwert der in
struct colvalue f
angegeben ist, in ein Array an Stelle nr ein. Dieses Array kann mittels
ws_showarray auf einen LED-Strang ausgegeben werden kann.
Parameter:
*ptr : Zeiger auf ein Array, das die
RGB Farbwerte aufnehmen soll
nr : LED-Nummer im Array, welche die
Position im Leuchtdiodenstrang
repraesentiert
struct colvalue *f : Zeiger auf einen RGB-Farbwert
ws_setegacol
--------------------------------------------
void ws_setegacol(uint8_t *ptr, uint16_t nr, uint8_t eganr)
setzt einen Farbwert aus der EGA-Palette in einem Array, das mittels
showarray auf einem LED-Strang
ausgegeben werden kann.
Parameter:
*ptr : Zeiger auf ein Array, das die
RGB Farbwerte aufnehmen soll
nr : LED-Nummer im Array, welche die
Position im Leuchtdiodenstrang
repraesentiert
eganr : Farbwert, der EGA-Palette
0..15 dunkle Farben
16..31 helle Farben
ws_blendup_left
--------------------------------------------
void ws_blendup_left(uint8_t *ptr, uint8_t anz, struct colvalue *f, int dtime)
blendet eine LED-Anzahl anz mit dem Farbwert, der in
struct colvalue f
angegeben ist, links schiebend auf. Hierfuer wird das Array, auf das *ptr
zeigt mit dem Farbwert aufgefuellt.
Verzoegerungszeit dtime bestimmt die Dauer eines Einzelschrittes beim Aufbau
in Millisekunden.
Parameter:
*ptr : Zeiger auf ein Array, das die
RGB Farbwerte aufnehmen soll
anz : Anzahl der Leuchtdioden im Strang
*f : Zeiger auf RGB-Farbwertstruktur die die Farbe der Auf-
blendung enthaellt
dtime : Verzoegerungszeit eines Schrittes beim Aufblenden
ws_blendup_right
--------------------------------------------
void ws_blendup_right(uint8_t *ptr, uint8_t anz, struct colvalue *f, int dtime)
blendet eine LED-Anzahl anz mit dem Farbwert, der in
struct colvalue f
angegeben ist, rechts schiebend auf. Hierfuer wird das Array, auf das *ptr
zeigt mit dem Farbwert aufgefuellt.
Verzoegerungszeit dtime bestimmt die Dauer eines Einzelschrittes beim Aufbau
in Millisekunden.
Parameter:
*ptr : Zeiger auf ein Array, das die
RGB Farbwerte aufnehmen soll
anz : Anzahl der Leuchtdioden im Strang
*f : Zeiger auf RGB-Farbwertstruktur die die Farbe der Auf-
blendung enthaellt
dtime : Verzoegerungszeit eines Schrittes beim Aufblenden
ws_buffer_rl
--------------------------------------------
void ws_buffer_rl(uint8_t *ptr, uint8_t lanz)
rotiert einen Pufferspeicher der die Leuchtdiodenmatrix enthaelt um eine LED-Position
nach links (also 3 Bytes) und fuegt hierbei die am Ende anstehende LED am Anfang
wieder ein.
Parameter:
*ptr : Zeiger auf ein Array, das die
RGB Farbwerte aufnehmen soll
lanz : Anzahl der Leuchtdioden im Strang
ws_buffer_rr
--------------------------------------------
void ws_buffer_rl(uint8_t *ptr, uint8_t lanz)
rotiert einen Pufferspeicher der die Leuchtdiodenmatrix enthaelt um eine LED-Position
nach rechts (also 3 Bytes) und fuegt hierbei die am Anfang anstehende LED am Ende
wieder ein.
Parameter:
*ptr : Zeiger auf ein Array, das die
RGB Farbwerte aufnehmen soll
lanz : Anzahl der Leuchtdioden im Strang
________________________________________________________________________________________________________________
Text und Software von R. Seelig
Jegliche Verwendung der Software und des Textes ist ausdruecklich erlaubt. Kommerzielle Nutzung der Software
inklusive dieses Textes insbesondere in gedruckter Form bedarf der Zustimmung des Authors R. Seelig