В этой статье представлена программа управления 1 RGB-светодиодом с помощью адресуемого драйвера RGB-светодиодов микросхемы WS2811. Производитель Worldsemi.

Микросхемы WS2811 позволяют по 1 линии управления устанавливать 1 из 16 млн цветов на любом RGB-светодиоде в цепи, которая может содержать до 512 пар микросхема WS2811 - RGB-светодиод. Для упрощения программы, в этой статье мы расскажем как управлять одним RGB-светодиодом.

Рис. 1. Принципиальная схема подключения RGB-светодиода к драйверу WS2811.

В качестве контроллера будем использовать Arduino UNO. Контакт DAT (см. рис. 1) подключим к D12 на плате Arduino.

Рис. 2. RGB-светодиод с драйвером WS2811 1 элемент от гирлянды подключён к плате Arduino UNO.

// bitTransfer 800 кГц WS2811

byte Orange[] = {255, 90, 0};
byte Blue[] = {0, 0, 255};
byte Black[] = {0, 0, 0};
byte White[] = {255, 255, 255};

extern "C" {
  extern __FlashStringHelper *rgbLed(int);
}

void setup() {
  rgbLed(&White);
  delay(1000);
  rgbLed(&Black);
  delay(1000);
}

void loop() {
  rgbLed(&Orange);
  delay(1000);
  rgbLed(&Blue);
  delay(1000);
}

Листинг 1. Программа управления RGB-светодиодом с помощью драйвера WS2811. Файл с расширением ino.

.global rgbLed
.equ SREG, 0x3f
.equ DDRB, 0x04
.equ PORTB, 0x05
.equ PIN_BIT, 4       ; PB4 - соответствует D12 на плате Arduino

rgbLed:               ; Передача 24 bit данных.
push r16
sbi DDRB, PIN_BIT     ; Настроить порт как выход
cbi PORTB, PIN_BIT    ; Низкий уровень на pin.
ldi r16, 0xd0         ; Задержка > 50 мкСек.
tratata:              ; Низкий уровень > 50 мкСек
nop                   ; это сигнал Reset,
dec r16               ; для выбора первого светодиода
brne tratata          ; в гирлянде.
movw X, r24           ; Загрузка в регистровую пару X адреса массива из 3 - х байт.
ld r16, X +           ; Загрузка в регистр уровня яркости для RED светодиода.
rcall byteTransfer
ld r16, X +           ; Загрузка в регистр уровня яркости для GREEN светодиода.
rcall byteTransfer
ld r16, X             ; Загрузка в регистр уровня яркости для BLUE светодиода.
rcall byteTransfer
pop r16
ret

byteTransfer:
rcall bitTransfer
rcall bitTransfer     ; 3 tacts
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
ret

; CPU F = 16 MGz  T = 0, 0625 mcSec
; Transfer F = 800 kGz    T = 1, 25 mcSec
; N = 1, 25 / 0, 0625 = 20 tacts
; T0H = 0, 25 mkC   4 tacts
; T0L = 0, 25 mkC  16 tacts
; T0L = 0, 6 mkC   10 tacts
; T0L = 0, 65 mkC  10 tacts

bitTransfer:
sbi PORTB, PIN_BIT    ; 2 tacts
rol r16               ; 1
brcs . + 2            ; 1 / 2
cbi PORTB, PIN_BIT    ; 2    если bit = 0
nop                   ; 1
nop                   ; 1
nop                   ; 1
nop                   ; 1
brcc . + 2            ; 1 / 2
cbi PORTB, PIN_BIT    ; 2    если bit = 1
nop                   ; 1
ret                   ; 4

; 0 HHHHLLLLLLLLLLLLLLLL
; 1 HHHHHHHHHHLLLLLLLLLL

Листинг 1. Программа управления RGB-светодиодом с помощью драйвера WS2811. Файл с расширением S.

Рис. 3. Осциллограмма, все 0.

Рис. 4. Осциллограмма, все 1.

Для того, чтобы снять осциллограммы рис. 1 и рис. 2 мы немного изменили ассемблерную часть программы.

.global rgbLed
.equ SREG, 0x3f
.equ DDRB, 0x04
.equ PORTB, 0x05
.equ PIN_BIT, 4      ; PB4 - соответствует D12 на плате Arduino

rgbLed:              ; Передача 24 bit данных.
sbi DDRB, PIN_BIT    ; Настроить порт как выход
cbi PORTB, PIN_BIT   ; Низкий уровень на pin.

ldi r19, 0xd0        ; Задержка > 50 мкСек.
tratata:             ; Низкий уровень > 50 мкСек
nop                  ; это сигнал Reset,
dec r19              ; для выбора первого светодиода
brne tratata         ; в гирлянде.
in r17, SREG         ; Запрет прерываний
cli

movw X, r24          ; Загрузка в регистровую пару X адреса массива из 3-х байт.
ld r16, X+           ; Загрузка в регистр уровня яркости для RED светодиода.
rcall byteTransfer
ld r16, X+           ; Загрузка в регистр уровня яркости для GREEN светодиода.
rcall byteTransfer
ld r16, X            ; Загрузка в регистр уровня яркости для BLUE светодиода.
rcall byteTransfer
out SREG, r17
ret

byteTransfer:
rcall bitTransfer
rcall bitTransfer          ; 3 tacts
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer          ; 3 tacts
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer          ; 3 tacts
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
rcall bitTransfer
RJMP byteTransfer
ret

; CPU F=16 MGz  T=0,0625 mcSec
; Transfer F=800 kGz    T=1,25 mcSec
; N=1,25/0,0625=20 tacts
; T0H=0,25 mkC   4 tacts
; T0L=0,25 mkC  16 tacts
; T0L=0,6 mkC   10 tacts
; T0L=0,65 mkC  10 tacts

bitTransfer:
sbi PORTB, PIN_BIT       ; 2 tacts
rol r16                  ; 1
brcs .+2                 ; 1/2
cbi PORTB, PIN_BIT       ; 2    если bit = 0
nop                      ; 1
nop                      ; 1
nop                      ; 1
nop                      ; 1
brcc .+2                 ; 1/2
cbi PORTB, PIN_BIT       ; 2    если bit = 1
nop                      ; 1
ret                      ; 4

; 0 HHHHLLLLLLLLLLLLLLLL
; 1 HHHHHHHHHHLLLLLLLLLL

Листинг 2. Программа для снятия осциллограмм управляющих сигналов для драйвера WS2811. Файл с расширением S.