// A2) STM8 -> WS2812B (STM8S208, 25MHz Xtal) // test driver for WS2812B using SPI (MOSI used as data ouput on PC6, SCK left unconnected, MISO free) // variant with 2bits in 1 SPI byte #include "stm8s.h" #include "milis.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 0b0100 // 333ns pulse, 999ns space #define H_PATTERN 0b0110 // 666ns pulse, 666ns space void main(void){ CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1); CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE); // 24MHz Xtal oscillator 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,tmp; 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 tmp=0; // combine two bit patterns into one byte there while(mask){ if(mask & data[length]){ // set high nibble with corresponding bit pattern tmp |= H_PATTERN<<4; }else{ tmp |= L_PATTERN<<4; } mask = mask >> 1; if(mask & data[length]){ // set low nibble with corresponding bit pattern tmp |= H_PATTERN; }else{ tmp |= L_PATTERN; } mask = mask >> 1; while(!(SPI->SR & SPI_SR_TXE)); // wait for empty SPI buffer SPI->DR = tmp; // send pattern with two pulses / two bits for WS2812 } } enableInterrupts(); while(SPI->SR & SPI_SR_BSY); // wait until end of transfer - now should come latch/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 | 2<<3; // Enable SPI as master at maximum speed (F_MCU/8, 24/2=3MHz) }