LEDCubeを作る(2) WS2812B点灯
LEDCubeを作る(1) 基板作成 - 今日やったこと で発注した基板も届き、LEDも届いたので光るか試した。
制御
http://akizukidenshi.com/download/ds/adafruit/WS2812B.pdf
データシートを読むにPWMのデューティーで0,1判定をしているそうなので(Duty=0%でリセット)適当にPWMを起こした。
#include <project.h> #define LED_N (4) #define LED_RESOLUTION (8) #define LED_COLOR (3) #define LED_RESET_DURATION (50) volatile uint16_t current_led = 0x0; volatile uint8_t current_color = 0x0; volatile uint8_t current_bit = 0x0; volatile uint8_t is_led_reset = 0x0; volatile uint8_t led_reset_counter = 0x0; volatile uint8_t color_data[LED_N][LED_COLOR] = { }; CY_ISR(pwm_ovf){ if(is_led_reset){ PWM_1_WriteCompare(0); if(led_reset_counter++ >= LED_RESET_DURATION){ is_led_reset = 0x0; } } else { PWM_1_WriteCompare((color_data[current_led][current_color] & (0x80 >> current_bit++)) ? 2 : 1); if(current_bit >= LED_RESOLUTION) { current_bit = 0x0; current_color++; } if(current_color >= LED_COLOR) { current_color = 0x0; current_led++; } if(current_led >= LED_N){ current_led = 0x0; is_led_reset = 0x1; led_reset_counter = 0x0; } } } int main() { uint32 i,j,k; PWM_1_Start(); PWM_1_WriteCompare(0); CyDelay(10); isr_PWM_OVF_StartEx(pwm_ovf); CyGlobalIntEnable; for(;;) { for(j = 0 ; j < LED_COLOR ; ++j){ for(i = 0 ; i < LED_N ; ++i){ for(k = 0 ; k < 0xffff ; ++k){ color_data[i][j] = (k >> 8); } } } for(j = 0 ; j < LED_COLOR ; ++j){ for(i = 0 ; i < LED_N ; ++i){ for(k = 0 ; k < 0xffff ; ++k){ color_data[i][j] = ~(k >> 8); } } } } }
DMAでLEDの書き換えをし続けるコンポーネントを作るかFPGAで制御したくなったが、FPGAなんざ使ったら本末転倒感がある。