There are a couple of ways to control WS2812B and its clones. Among them, the method that uses SPI bus via DMA would be the easiest choice for the following reasons; Firstly SPI bus is ubiquitous. It is not easy to find a MCU that is not equipped with one. Secondly DMA minimizes the burden of the processor and handles timing with hardware. No code is involved in transferring data. Thus once proper SPI clock is chosen, operation is quite reliable as well. Only downside is that you have to dedicate one SPI port for the control of the LED, since you cannot share this line with any other SPI devices.
The timing of SK6812 is shown below. There are slight variations in the actual timing between devices. But basically all use the same high/low ratio, namely 1:3 for logic zero and 2:2 for logic one.
Thus set the SPI clock frequency to somewhere between 2.8hMHz and 4MHz, and use nibble (0x8) for logic zero, (0xc) for logic one. Then all should be good.
Actually there are a few things to think about but let's check the timing first. The main clock was 12MHz , the SPI clock was 3MHz (divided by 4), and value [0x88] was sent to the LED string. In the picture below, the waveform shown above is MOSI signal sending [0x88], and below is SCLK signal.
From the measurement, you can see that the width of the pulse is about 340nsec, 333nsec to be exact, and the width of zero period is 1000nsec, which fits the specification of logic zero.
First thing to consider is that if you do not use DMA but use code to send a stream of data to SPI bus one by one, you will certainly see a gap between two consecutive data, which dose not recognized by the LED.
Second thing is when the SPI started to send its first byte, it goes from zero to one sometime before its first clock appears if the first bit is one. It is shown in the following picture. MOSI waveform shown above leads the SPI clock below by 400nsec or so.
Thus although the same [0x88] is sent as before, its width is a bit thicker than the specification due to this. This will confuse the logic in the LED. To avoid this, your data stream should start with (0x0) nibble always. And actual data comes at the second nibble.
The result is as expected. The board on the right (a ST micro discovery series board) is used to program the device (STM32L052) on the left.
<<Source Code>>
The timing of SK6812 is shown below. There are slight variations in the actual timing between devices. But basically all use the same high/low ratio, namely 1:3 for logic zero and 2:2 for logic one.
Actually there are a few things to think about but let's check the timing first. The main clock was 12MHz , the SPI clock was 3MHz (divided by 4), and value [0x88] was sent to the LED string. In the picture below, the waveform shown above is MOSI signal sending [0x88], and below is SCLK signal.
From the measurement, you can see that the width of the pulse is about 340nsec, 333nsec to be exact, and the width of zero period is 1000nsec, which fits the specification of logic zero.
First thing to consider is that if you do not use DMA but use code to send a stream of data to SPI bus one by one, you will certainly see a gap between two consecutive data, which dose not recognized by the LED.
Second thing is when the SPI started to send its first byte, it goes from zero to one sometime before its first clock appears if the first bit is one. It is shown in the following picture. MOSI waveform shown above leads the SPI clock below by 400nsec or so.
Thus although the same [0x88] is sent as before, its width is a bit thicker than the specification due to this. This will confuse the logic in the LED. To avoid this, your data stream should start with (0x0) nibble always. And actual data comes at the second nibble.
The result is as expected. The board on the right (a ST micro discovery series board) is used to program the device (STM32L052) on the left.
<<Source Code>>
Comments
Post a Comment