-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathws2812b.c
181 lines (146 loc) · 4.96 KB
/
ws2812b.c
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
/* -------------------------------------------------------
ws2812b.c
Softwaremodul zur Ansteuerung von WS2812b Leucht-
dioden, Leuchtdiodenreihen
MCU : STM8S103F3
Hardware : WS2812b Leuchtdiodenreihe
Takt : interner Takt 16 MHz
Compiler : SDCC 3.5
88.05.2017 R. Seelig
------------------------------------------------------ */
#include "ws2812b.h"
/*
##################################################################
STM8S103F3P6 Pinout
##################################################################
------------
UART1_CK / TIM2_CH1 / PD4 | 1 20 | PD3 / AIN4 / TIM2_CH2 / ADC_ETR
UART1_TX / AIN5 / PD5 | 2 19 | PD2 / AIN3
UART1_RX / AIN6 / PD6 | 3 18 | PD1 / SWIM
NRST | 4 17 | PC7 / SPI_MISO
OSCIN / PA1 | 5 16 | PC6 / SPI_MOSI
OSCOUT / PA2 | 6 15 | PC5 / SPI_CLK
Vss (GND) | 7 14 | PC4 / TIM1_CH4 / CLK_CCO / AIN2
VCAP (*1) | 8 13 | PC3 / TIM1_CH3 /
Vdd (+Ub) | 9 12 | PB4 / I2C_SCL
TIM2_CH3 / PA3 | 10 11 | PB5 / I2C_SDA
-----------
*1 : Ist mit min. 1uF gegen GND zu verschalten
/* ----------------------------------------------------------
ws_reset
setzt die Leuchtdiodenreihe (fuer einen folgenden
Datentransfer zu den Leuchtdioden) zurueck
---------------------------------------------------------- */
void ws_reset(void)
{
__asm
bres gpio_asm, #gpio_pin // Datenpin des LED-Strangs auf 0 setzen
__endasm;
delay_us(100);
}
/* -------------------------------------------------------------
ws_showarray
(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)
funktionieren.
Uebergabe:
*ptr : Zeiger auf ein Array, das angezeigt
werden soll
anz : Anzahl der anzuzeigenden LED's
------------------------------------------------------------- */
void ws_showarray(uint8_t *ptr, int anz)
{
ptr;
anz;
__asm
push a
pushw x
pushw y // auf dem Stack liegt (in dieser Reihenfolge)
// int anz ( 2 Byte )
// Zeiger ptr ( 2 Byte )
// Ruecksprungadresse ( 2 Byte )
// a ( 1 Byte )
// x ( 2 Byte )
// y ( 2 Byte )
ldw y,(0x0a, sp) // 10. Position auf dem Stack = int anz
// anz= (anz*3)-1 => jede LED 3 Byte Speicherbedarf erfordert n*3
// Sendevorgaenge;
addw y,(0x0a, sp)
addw y,(0x0a, sp)
decw y
ldw x,(0x08, sp) // 8. Position = *ptr
array_loop:
pushw y // Anzahl der noch zu sendenden Bytes auf den Stack
ld a,(x) // a enthaellt den ersten Wert, auf den PTR zeigt
ldw y,#0x0007 // 8 Shifts fuer 1 Byte
loop0:
rlc a // ist hoechstwertigstes gesetzt
jrc sendhi // dann eine 1 senden
sendlo:
// 0 - senden
bset gpio_asm, #gpio_pin
nop
nop
bres gpio_asm, #gpio_pin
nop
nop
nop
nop
nop
nop
nop
nop
jra loop0_end
sendhi:
// 1 - senden
bset gpio_asm, #gpio_pin
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
bres gpio_asm, #gpio_pin
nop
nop
loop0_end:
decw y
jrpl loop0
incw x
popw y
decw y
jrpl array_loop
popw y
popw x
pop a
__endasm;
}
/* ----------------------------------------------------------
ws_clrarray
loescht ein LED Anzeigearray
Parameter:
*ptr : Zeiger auf ein Array, das
geloescht werden soll
anz : Anzahl der LEDs, die angezeigt
werden sollen
---------------------------------------------------------- */
void ws_clrarray(uint8_t *ptr, int anz)
{
int i;
for (i= 0; i< (anz*3); i++)
{
*ptr = 0x00;
ptr++;
}
}