// A) STM8 -> WS2812B (STM8S208, 16MHz internal RC) // test driver for WS2812B using SPI (MOSI used as data ouput on PC6, SCK left unconnected) // Possible release MISO using BIDIrectional mode #include "stm8s.h" #include "milis.h" //#include "stdio.h" //#include "spse_stm8.h" //#include "stm8_hd44780.h" void init_spi(void); void test(uint8_t* data, uint16_t delka); // test pattern for (12 RGB LED ring) uint8_t colors[36]={ 0xff,0x00,0x00, // B 0x00,0xff,0x00, // R 0x00,0x00,0xff, // G 0x00,0x00,0x00, // black 0x2f,0x2f,0x2f // light white }; #define L_PATTERN 0b01110000 // 3x125ns (8MHZ SPI) #define H_PATTERN 0b01111100 // 5x125ns (8MHZ SPI), first and last bit must be zero (to remain MOSI in Low between frames/bits) void main(void){ CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); // 16MHz from internal RC init_milis(); // millis using TIM4 - not necessary init_spi(); while (1){ test(colors,sizeof(colors)); // transfer image into RGB LED string delay_ms(2); // wait some time } } // takes array of LED_number * 3 bytes (RGB per LED) void test(uint8_t* data, uint16_t length){ uint8_t mask; disableInterrupts(); // can be omitted if interrupts do not take more then about ~25us while(length){ // for all bytes from input array length--; mask=0b10000000; // for all bits in byte while(mask){ while(!(SPI->SR & SPI_SR_TXE)); // wait for empty SPI buffer if(mask & data[length]){ // send pulse with coresponding length ("L" od "H") SPI->DR = H_PATTERN; }else{ SPI->DR = L_PATTERN; } mask = mask >> 1; } } enableInterrupts(); while(SPI->SR & SPI_SR_BSY); // wait until end of transfer - there should come "reset" (>50us in Low) } void init_spi(void){ // Software slave managment (disable CS/SS input), BiDirectional-Mode release MISO pin to general purpose SPI->CR2 |= SPI_CR2_SSM | SPI_CR2_SSI | SPI_CR2_BDM | SPI_CR2_BDOE; SPI->CR1 |= SPI_CR1_SPE | SPI_CR1_MSTR; // Enable SPI as master at maximum speed (F_MCU/2, there 16/2=8MHz) }