// B) STM8 -> WS2812B (STM8S208, 16MHz internal RC) // test driver for WS2812B using TIM1 (CH1 used as data ouput, using One-Pulse mode) // edit to use another channel #include "stm8s.h" #include "milis.h" void test(uint8_t* data, uint16_t delka); void init_tim(void); // 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_PULSE 6 // 6*1/16MHz = 6*62.5 = 375ns (~400ns) #define H_PULSE 12 // 12*1/16MHz = 12*62.5 = 750ns (~800ns) void main(void){ CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); // 16MHz from internal RC init_milis(); // millis using TIM4 - not necessary init_tim(); while (1){ test(colors,sizeof(colors)); delay_ms(2); } } void init_tim(void){ GPIO_Init(GPIOC,GPIO_PIN_1,GPIO_MODE_OUT_PP_LOW_FAST); // PC1 (TIM1_CH1) TIM1_TimeBaseInit(0, TIM1_COUNTERMODE_UP, 15, 0); // Upcounting, prescaler 0, dont care period/ARR value // OC1 as output with Polarity High in PWM2 mode (OC1N not used) TIM1_OC1Init(TIM1_OCMODE_PWM2, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_DISABLE, 1, TIM1_OCPOLARITY_HIGH, TIM1_OCNPOLARITY_HIGH, TIM1_OCIDLESTATE_SET, TIM1_OCNIDLESTATE_RESET); TIM1_CtrlPWMOutputs(ENABLE); // Timer output global enable TIM1_SelectOnePulseMode(TIM1_OPMODE_SINGLE); // Selecting One Pulse Mode } // 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(TIM1->CR1 & TIM1_CR1_CEN); // wait if timer run (transmitting last bit) if(mask & data[length]){ // send pulse with coresponding length ("L" od "H") TIM1->ARRL = H_PULSE; // set pulse width for "H" bit }else{ TIM1->ARRL = L_PULSE; // set pulse width for "L" bit } TIM1->CR1 |= TIM1_CR1_CEN; // Start timer (start single pulse generation) mask = mask >> 1; } } enableInterrupts(); } // pod tímto komentáøem nic nemìòte #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval : None */ void assert_failed(u8* file, u32 line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif