// C) STM8 -> WS2812B (STM8S208, 16MHz internal RC) // test driver for WS2812B using TIM3 (CH1 used as data ouput, using One-Pulse mode, datasheet claims that it is not possible to use One-Pulse mode ! :D) // edit to use another channel #include "stm8s.h" #include "milis.h" //#include "stdio.h" //#include "spse_stm8.h" //#include "stm8_hd44780.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(GPIOA,GPIO_PIN_3,GPIO_MODE_OUT_PP_LOW_FAST); // PA3 (TIM3_CH1) as output TIM3_OC1Init(TIM3_OCMODE_PWM2, TIM3_OUTPUTSTATE_ENABLE,1, TIM3_OCPOLARITY_HIGH); // One-Pulse configuration (with CCR1/delay=1) TIM3_TimeBaseInit(TIM3_PRESCALER_1, L_PULSE); // Selecting prescaler (Period/ARR value will be set to relevant value later) TIM3_SelectOnePulseMode(TIM3_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(TIM3->CR1 & TIM3_CR1_CEN); // wait until timer stops (wait if transmitting last bit) if(mask & data[length]){ // send pulse with coresponding length ("L" od "H") TIM3->ARRL = H_PULSE; // set pulse width for "H" bit }else{ TIM3->ARRL = L_PULSE; // set pulse width for "L" bit } TIM3->CR1 |= TIM3_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