📜 ⬆️ ⬇️

Using configurable logic cells PIC microcontrollers to control WS2812

This article is about controlling the WS2812b LEDs, a little about the synthesis of logic circuits and their implementation inside the microcontroller. Article with small digressions and two bonuses. The first bonus is based on the fact that when we write, we read at the same time (isn’t it?). The second bonus will help you start programming microcontrollers and in 10 minutes you can repeat the implementation described in the article.

Three-color “SPI LEDs” WS2812b (Fig. 1) with a driver and their predecessors WS2811 / WS2812 are connected in series and controlled via a single-wire (serial) bus (hence sometimes mistakenly called “SPI LEDs”, although in the described case, especially for “bonus # 1 "SPI plays a key role). Each RGB color bit (24 bits, 8 bits per channel) is encoded by a PWM signal (see Figure 2), with a period of about 1.25 μs. WS2812 LEDs are often used in controlled LED strips and screens, as they have a fast and simple interface, and the number of LEDs is easily increased. So, for example, at a frequency of 25 frames per second, a video screen can contain one line of (40ms - 50 µs) / (0.125 µs x 24) ~ = 1300 RGB LEDs. It is not so much, but for advertising signs, a board or a running line can be quite enough.


Fig. 1. LED strip with digital serial interface


Fig. 2. Bit sequence coding parameters
')
The use of cheap microcontrollers for the formation of such short signals (see Fig. 2) presents certain difficulties. So, for example, for a PIC16 controller with a clock frequency of 16 MHz, one command is executed for 250 ns. Thus, for software control of the WS2812 driver, it is necessary to spend almost 100% of the kernel speed.

Interface synthesis

To solve the problem, one could use the hardware capabilities of the microcontroller, for example, the SPI interface. Often use such a trick, when for the transfer of "zero" transmit the sequence "11100000", and for the "unit" - "11111000", i.e. one bit is encoded byte (or nibble).

Another way is to use the SPI interface and logic elements. In the application notes [1] and [2], examples are published on which the described implementation is mainly based.

So, if we take the SPI interface signals and invert the SCK signal (synchronization signal) and combine it with the SDO (output) logical AND function, we will get the coded “Units” (Fig. 3).


Fig. 3. Coding "units"

To encode "Zeros" need another signal with a shorter duration. To do this, you can use the PWM microcontroller. The “zeros” are encoded by the signal described by the logical expression n (SDO) * n (SCK) * PWM (n is the inverse). It is this expression that is given in [1] and [2], but, as can be seen from the final diagram (Figure 5), or derived from the synthesis of a logic circuit using the truth table and Carnot maps, the expression can be written as nSCK * PWM.


Fig. 4. Coding "zeros"

It remains to combine the “Zero” and “Units” streams with the OR function, and obtain the PWM sequence required for controlling the WS2811 / WS2812 driver.


Fig. 5. Result of stream coding

In the form of a logical expression, the control signal is written as:
(nSCK * SDO) + ​​(nSDO * nSCK * PWM) {1}

Using the theorems of Boolean algebra (see, for example, the remarkable textbook [3]) it can be shown that the expression {1} is converted to equivalent expressions:
n (SCK + nSDO) + ​​n (SDO + SCK + nPWM) {2}
(nSCK * PWM) + (nSCK * SDO) {3}
n (SCK + nPWM) + n (SCK + nSDO) {4}
nSCK * (PWM + SDO) {5}

Many younger Microchip microcontrollers, such as the PIC16F1508, PIC16F1509, have built-in Configurable Logic Cell (CLC).

Configurable logic cells are core-independent peripherals, which can help in the implementation of the microcontroller's logic-related operation and external signals. Asynchrony from the kernel and independence from the program allows you to implement functions that are difficult to implement only programmatically.

Input signals for the CLC can be the input signals of the microcontroller, the outputs of the CLC, other embedded peripheral modules and internal generators. CLC outputs can be output to ports and shared with other peripherals of controllers.

Given the above, a bunch of SPI interface and CLC looks like an ideal option for solving the problem of generating the control signal of the WS2812 LED driver (WS2811).

The CLC Designer utility is used to visually configure the CLC and generate the code. You can also configure the microcontroller peripherals through the Mplab Code Configurator (MCC) plugin to the MPLAB X development environment.

Not all combinations of input signals are present at the inputs of logic cells. Therefore, it is necessary to find such a combination of signals and cells that are needed to perform a specific task. To encode data on CLC cells, we need SCK, SDO and PWM signals. The logic cell CLC4 at its inputs can have signals from SCK, SDO, but does not have a signal from PWM, and CLC2 can have PWM at its inputs. The CLC2 output can be connected to the CLC4 input. Therefore, CLC2 will act as a repeater and transmit PWM to the input of CLC4, and CLC4 will perform the logical function of the expressions {1}, {2}, ... {5}.


Fig.6. CLC2 transmits PWM to output. Gate2 - 4 have log.1 output and do not affect the final result

In fact, the function {1} in the above form cannot be implemented on a single CLC cell, but its equivalent forms {2} ... {5} are easy. (see fig. 7).


Fig. 7. CLC4 generates PWM coding of SPI signal through the function n (SCK + SDA + nPWM) + n (SCK + SDA)

In this case, an additional D-trigger is applied, which allows the input signals to be out of sync with respect to the clock frequency of the controller and to avoid false switching of the output. In general, for a specific case, a D-flip-flop may not be necessary, but such a configuration gives more predictable output timings (synchronization from the FOSC clock frequency).

Retreat # 1. Five ways to solve one problem
The implementation of logic functions {2} ... {5} is shown in fig. 7a ... 7g. All expressions are equivalent and give the expected result (see Fig. 5).


Fig. 7a. (nSCK * PWM) + (nSCK * SDO)


Fig. 7b. n (SCK + nPWM) + n (SCK + nSDO)


Fig. 7c. nSCK * (PWM + SDO)


Fig. 7g. n (SCK + SDA + nPWM) + n (SCK + SDA)

Retreat # 2. Parasitic pulses in combinational logic circuits
There are situations when a change in the input signal leads to several changes in the output, resulting in the formation of a parasitic pulse (glitch). This can happen if the changing input signal passes to the output in several ways and the number of passable logic gates in different ways is different. Then, due to the delay of each of the logical elements and the difference in travel time along the “shortest” and “critical” paths, the formation of a parasitic pulse is possible. This process is well described in [3].
For our specific example, when implementing the functions {1} ... {5}, such situations do not arise, but even if it did, the problem can be solved using the OR-D configuration of the configured cells. Then the scheme with fig.7g can be redrawn as in fig. 7 (d), where the additional D-trigger captures the value at the output on the front of the clock frequency signal of the FOSC controller.


Fig. 7e. The same function as in fig. 7d., But with a latch on the way out


So, after the configuration of the CLC, PWM and SPI is done, the preparatory part is over. Now, if we write a byte to the SSP1BUF register, then at the output of the CLC4 we will get an encoded PWM signal in accordance with the WS2812 format. While the SPI module is transmitting data, the microcontroller can perform some other tasks. For each LED, you need to transfer three bytes. Connection diagram is shown in Fig. eight.


Fig. 8. Connecting a WS2812b tape to a microcontroller

Bonus # 1. Memory increase

In the described method, the configurable logic and its joint operation with the microcontroller's periphery ensures the formation of protocol time parameters in the WS2812 format, the program is only required to write a byte to the SPI buffer, the configurable logic cells assume further “magic”. Since in the described example SPI is used only for recording, and the input SDI line remains free, there is an excellent opportunity to use SPI not only to control the LEDs, but also to simultaneously receive external data. Consider how simultaneously with the management of LEDs to read data from the memory chip with SPI interface.

The SPI port of the PIC microcontroller has two shift registers (one for transmission, one for receiving) with one address. Writing to SSPBUF will start byte transmission and shifts bitiki to the SDO line, but at the same time the data from the input SDI line is shifted to the same register. That is, by transferring a byte to SPI (SDO), we simultaneously receive data from SPI (SDI).



Thus, if WS2812 LEDs and, for example, SPI memory (SRAM 23LC512 or EEPROM 25LCxxx) are connected to the SPI module of the microcontroller, then the program needs only to transfer the data from the SSPBUF to the SSPBUF, i.e. read the byte from the external memory and the next command to send the data back to the SPI (to the LEDs) and simultaneously read the next byte, etc.



Fig. 9. Connecting external memory

When writing a dataset to external SPI memory or reading the first byte from memory, you need to disable the output of the CLC4 in order not to give out “garbage” to the LEDs.

Depending on how often you need to update the array of LEDs, the number of LEDs can be very large - it is limited by the update rate and the size of external memory. From the lines of LEDs, you can create LED screens and displays. The data in the display buffer can be changed while the image is not updated, it also gives time for more complex calculations, table searches, etc., which is necessary to build the displayed image.

The presence of a buffered image in external memory allows you to display moving images by shifting the starting address of the read memory. With SPI EEPROM memory, you can display pre-recorded images. The SPI interface allows you to connect multiple memory chips, for example, one EEPROM for storing character generator, static images, and in the second SRAM create a display buffer for subsequent output to the LED screen.

Bonus # 2. Do it yourself

To study the sources, you can go to the Microchip website (source code for the example AN1890 is available on the website

But I propose to watch a short video where in five minutes it is shown how to create all the above described magic with your own hands.



Sources


1. AN1606. Using the Configurable Logic Cell (CLC) to Interface a PIC16F1509 and WS2811. LED Driver www.microchip.com
2. AN1890. Simple SRAM Buffering for Large LED Arrays. www.microchip.com
3. D. Harris, S. Harris. “Digital circuit design and computer architecture” (http://habrahabr.ru/post/259505/)

Source: https://habr.com/ru/post/262285/


All Articles