(08-12-2019, 17:52)busyboy napisał(a): Panowie, to może konkretnie odpowiecie na moje pytanie? bo z tego co widać na tym uC co mam to nie działa niestetyKażdy uC z dwoma UART lub SPI a w wielu przypadkach I2C, DMA które obsłużą peryferia, RAM o wielkości wymaganej przez LED.
Co mam zakupić ? jaki uC ? aby obsłużył równocześnie ws2811 i ws2812b ? 100%
Z oczywistych względów AVR odpada. Xmega jest droga dlatego proponuję STM32. Ze względu na to, że wykorzystanie UART ma kilka zalet ale wymaga zanegowania sygnału na linii TX trzeba wybrać uC z możliwością sprzętowego negowania sygnału. LED wymagają sterowania sygnałem C-MOS, typowo zasilany STM32 z 3,3V nie zapewni gwarantowanego 3,5V przy zasilaniu LED 5V. Na szczęście ustawienie wyjścia w tryb OD i rezystor podciągający to =5V rozwiążą problem w przypadku większości STM. Dla niedużej ilości LED wystarczy STM32F07x. F03x też jest ok ale nie ma USB a ono przydaje się.
Nie potrzebujesz żadnych bibliotek!
Chyba, że konieczne chcesz w bibliotece umieścić:
Kod:
HAL_UART_Transmit_DMA( &huart1, scr, WSLED * 8 );
Kod:
//----------------------------------------------------------------------//
void WS2812B_transcodeRGB_Gamma(uint8_t red, uint8_t green, uint8_t blue, byte *buffer ) //Przekonwertuj podany kolor w formacie GRB na ciag 8 bajtów dla USART
{
red = Gamma256Correct( red );
green = Gamma256Correct( green );
blue = Gamma256Correct( blue );
WS2812B_transcodeRGB( red, green, blue, buffer );
}
//----------------------------------------------------------------------//
void WS2812B_transcodeRGB(uint8_t red, uint8_t green, uint8_t blue, byte *buffer ) //Przekonwertuj podany kolor w formacie GRB na ciag 8 bajtów dla USART
{
// if( blink7seg && FL_BlinkWS2812 ) red = green = blue = 0;
if ( scr - buffer > WSLED * 8 )
{
TRAP;
return;
}
for (byte x = 0; x < 8; x++) *(buffer + x) = b00100100; // Czyscimy bufor
// EccBBBaaS
// 0b1011011; // Off
// 0b0010010; // On
// ***
if ( green & 0x80 ) *(buffer + 0) |= ~(b01111110);
// ***
if ( green & 0x40 ) *(buffer + 0) |= ~(b01110011);
// ***
if ( green & 0x20 ) *(buffer + 0) |= ~(b00011111);
if ( green & 0x10 ) *(buffer + 1) |= ~(b01111110);
if ( green & 0x08 ) *(buffer + 1) |= ~(b01110011);
if ( green & 0x04 ) *(buffer + 1) |= ~(b00011111);
if ( green & 0x02 ) *(buffer + 2) |= ~(b01111110);
if ( green & 0x01 ) *(buffer + 2) |= ~(b01110011);
if ( red & 0x80 ) *(buffer + 2) |= ~(b00011111);
if ( red & 0x40 ) *(buffer + 3) |= ~(b01111110);
if ( red & 0x20 ) *(buffer + 3) |= ~(b01110011);
if ( red & 0x10 ) *(buffer + 3) |= ~(b00011111);
if ( red & 0x08 ) *(buffer + 4) |= ~(b01111110);
if ( red & 0x04 ) *(buffer + 4) |= ~(b01110011);
if ( red & 0x02 ) *(buffer + 4) |= ~(b00011111);
if ( red & 0x01 ) *(buffer + 5) |= ~(b01111110);
if ( blue & 0x80 ) *(buffer + 5) |= ~(b01110011);
if ( blue & 0x40 ) *(buffer + 5) |= ~(b00011111);
if ( blue & 0x20 ) *(buffer + 6) |= ~(b01111110);
if ( blue & 0x10 ) *(buffer + 6) |= ~(b01110011);
if ( blue & 0x08 ) *(buffer + 6) |= ~(b00011111);
if ( blue & 0x04 ) *(buffer + 7) |= ~(b01111110);
if ( blue & 0x02 ) *(buffer + 7) |= ~(b01110011);
if ( blue & 0x01 ) *(buffer + 7) |= ~(b00011111);
}
Kod:
uint8_t Gamma256Correct( byte in )
{
return ( gamma256[ in ] );
}
Kod:
const uint8_t gamma256[256] = {
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // Tu byly tylko zera
1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, // Od tad pojawila sie jedynka
4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9,
9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 14,
14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22,
23, 23, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30, 31, 32, 33,
33, 34, 35, 36, 36, 37, 38, 39, 39, 40, 41, 42, 43, 43, 44, 45, 46,
47, 48, 49, 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, 81, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 95, 96,
97, 98, 100, 101, 102, 103, 105, 106,
107, 108, 110, 111, 112, 114, 115, 116,
118, 119, 121, 122, 123, 125, 126, 127,
129, 130, 132, 133, 135, 136, 138, 139,
141, 142, 144, 145, 147, 148, 150, 151,
153, 154, 156, 157, 159, 160, 162, 164,
165, 167, 169, 170, 172, 173, 175, 177,
178, 180, 182, 183, 185, 187, 189, 190,
192, 194, 196, 197, 199, 201, 203, 204,
206, 208, 210, 212, 213, 215, 217, 219,
221, 223, 225, 226, 228, 230, 232, 234,
236, 238, 240, 242, 244, 246, 248, 250,
252, 255, 255
};
Dla bajeru przyda się
Kod:
//----------------------------------------------------------------------//
void Interpolacja( byte *red, byte *green, byte *blue, byte Rs, byte Gs, byte Bs, byte Rd, byte Gd, byte Bd, byte liczna_krokow, byte krok ) {
// *reg, green, blue - wskaznik na dane wyjsciowe
// Rs, g, b - dane poczatkowe
// Rd, g, b - dane koncowe
// liczna_krokow - liczba led
// krok - nr diody
*red = ((Rd - Rs) * krok) / liczna_krokow + Rs; // Interpolacja skladowych
*green = ((Gd - Gs) * krok) / liczna_krokow + Gs;
*blue = ((Bd - Bs) * krok) / liczna_krokow + Bs;
}
Ile LED chcesz docelowo wysterować?
EDIT:
(08-12-2019, 18:14)elvis napisał(a): Moim zdaniem ten projekt da się zrobić na właściwie każdym układzieTo zrób równoczesna transmisję do dwóch pasków na AVR jeśli z jednym sobie ledwo radzi. o Z-80 nie wspomnę.
(08-12-2019, 18:14)elvis napisał(a): Dlatego napisałem żeby najpierw poszukać gotowej biblioteki, która obsługuje odpowiednio długie łańcuchy. Ja takiej biblioteki niestety nie znam.A swojej nie napisałeś? Jeśli twierdzisz, że nawet Z-80 poradzi sobie z WS281x to aż dziwne, że nie potrafisz napisać obsługi kilku tysięcy LED.