ATtiny85开发板Digispark淘宝上非常多,使用也非常简单,无需额外的编程器,配置好Arduino IDE,插入USB口就可以开始编程了。
为Arduino IDE添加Digispark支持:
http://digistump.com/wiki/digispark/tutorials/connectingpro
添加支持时的文件存放在aws中,需要修复hosts文件,才能正常访问
# Github # Amazon AWS Start 54.239.31.69 aws.amazon.com 54.239.30.25 console.aws.amazon.com 54.239.96.90 ap-northeast-1.console.aws.amazon.com 54.240.226.81 ap-southeast-1.console.aws.amazon.com 54.240.193.125 ap-southeast-2.console.aws.amazon.com 54.239.54.102 eu-central-1.console.aws.amazon.com 177.72.244.194 sa-east-1.console.aws.amazon.com 176.32.114.59 eu-west-1.console.aws.amazon.com 54.239.31.128 us-west-1.console.aws.amazon.com 54.240.254.230 us-west-2.console.aws.amazon.com 54.239.38.102 s3-console-us-standard.console.aws.amazon.com 54.231.49.3 s3.amazonaws.com 52.219.0.4 s3-ap-northeast-1.amazonaws.com 54.231.242.170 s3-ap-southeast-1.amazonaws.com 54.231.251.21 s3-ap-southeast-2.amazonaws.com 54.231.193.37 s3-eu-central-1.amazonaws.com 52.218.16.140 s3-eu-west-1.amazonaws.com 52.92.72.2 s3-sa-east-1.amazonaws.com 54.231.236.6 s3-us-west-1.amazonaws.com 54.231.168.160 s3-us-west-2.amazonaws.com 52.216.80.48 github-cloud.s3.amazonaws.com 54.231.40.3 github-com.s3.amazonaws.com 52.216.20.171 github-production-release-asset-2e65be.s3.amazonaws.com 52.216.228.168 github-production-user-asset-6210df.s3.amazonaws.com
点亮WS2811有很多现有的非常好用的库,如:Adafruit_NeoPixel,但是这些库需要设置灯珠颜色需要事先建立颜色数组,而ATtiny85运行空间只有512字节,按照此方式最多可点亮100个灯珠。所以要想点亮更多的灯珠只有另外想办法了。
下面代码中的fill方法可填充最少上千个节点。可用于测试和一些变换效果。
#define PIN 1 #define NUMPIXELS 2048 volatile uint8_t *ws2812_port; uint8_t pinMask; uint8_t loop_count; void ws2811_init(); void ws2811_reset(); void ws2811_send_array(uint8_t *data, uint16_t data_len, uint8_t maskhi, uint8_t *port); void ws2811_set_color(unsigned int r, unsigned int g, unsigned int b ); void ws2811_set_colors(uint8_t *data, uint8_t data_len); void ws2811_fill(uint8_t *color, uint16_t led_pixels, uint8_t maskhi, uint8_t *port); void ws2811_repeat(uint8_t (*color_table)[3], uint16_t color_table_size); void setup() { // initialize the digital pin as an output. pinMode(PIN, OUTPUT); // LED on Model A loop_count = 0; ws2811_init(); } void loop() { ws2811_reset(); // // first led color // ws2811_set_color(random(255), random(255), random(255)); // // // color sequeue // uint8_t data[] = {random(255),random(255),random(255), random(255),random(255),random(255)}; // ws2811_set_colors(data, 6); // // all led same color // uint8_t color[] = {random(255),random(255),random(255)}; // ws2811_fill(color, pinMask, (uint8_t*)ws2812_port); // grb uint8_t color_table[][3] = {{255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {255, 0, 255}, {0, 255, 255}}; ws2811_repeat(color_table, sizeof(color_table)/sizeof(color_table[0])); delay(1000); } void ws2811_init() { pinMask = digitalPinToBitMask(PIN); ws2812_port = portOutputRegister(digitalPinToPort(PIN)); } void ws2811_reset() { digitalWrite(PIN, LOW); delayMicroseconds(50); } void ws2811_fill(uint8_t *color, uint16_t led_pixels, uint8_t maskhi, uint8_t *port) { uint8_t curbyte,ctr,masklo; uint8_t sreg_prev; masklo = ~maskhi & *port; maskhi |= *port; sreg_prev = SREG; cli(); for(int i=0; i<led_pixels; i++) { uint8_t color_size = 3; uint8_t *p; p = color; while (color_size--) { curbyte = *p++; asm volatile( " ldi %0,8 \n\t" "loop%=: \n\t" " st X,%3 \n\t" // '1' [02] '0' [02] - hi " rjmp .+0 \n\t" // 2 nop " sbrs %1,7 \n\t" // '1' [04] '0' [03] - if bitset jump " st X,%4 \n\t" // '1' [--] '0' [05] - lo " lsl %1 \n\t" // '1' [05] '0' [06] - left move " rjmp .+0 \n\t" // 2 nop " brcc skipone%= \n\t" // '1' [+1] '0' [+2] - if bitclr jump " st X,%4 \n\t" // '1' [+3] '0' [--] - lo " nop \n\t" "skipone%=: " // '1' [+3] '0' [+2] - " rjmp .+0 \n\t" // 2 nop " nop \n\t" " dec %0 \n\t" // '1' [+4] '0' [+3] " brne loop%=\n\t" // '1' [+5] '0' [+4] : "=&d" (ctr) : "r" (curbyte), "x" (port), "r" (maskhi), "r" (masklo) ); } } SREG = sreg_prev; } void ws2811_repeat(uint8_t (*color_table)[3], uint16_t color_table_size) { uint8_t *color; color = color_table[loop_count % color_table_size]; ws2811_fill(color, NUMPIXELS, pinMask, (uint8_t*)ws2812_port); loop_count ++; } void ws2811_send_array(uint8_t *data, uint16_t data_len, uint8_t maskhi, uint8_t *port) { uint8_t curbyte,ctr,masklo; uint8_t sreg_prev; masklo = ~maskhi & *port; maskhi |= *port; sreg_prev = SREG; cli(); while (data_len--) { curbyte=*data++; asm volatile( " ldi %0,8 \n\t" "loop%=: \n\t" " st X,%3 \n\t" // '1' [02] '0' [02] - hi " rjmp .+0 \n\t" // 2 nop " sbrs %1,7 \n\t" // '1' [04] '0' [03] - if bitset jump " st X,%4 \n\t" // '1' [--] '0' [05] - lo " lsl %1 \n\t" // '1' [05] '0' [06] - left move " rjmp .+0 \n\t" // 2 nop " brcc skipone%= \n\t" // '1' [+1] '0' [+2] - if bitclr jump " st X,%4 \n\t" // '1' [+3] '0' [--] - lo " nop \n\t" "skipone%=: " // '1' [+3] '0' [+2] - " rjmp .+0 \n\t" // 2 nop " nop \n\t" " dec %0 \n\t" // '1' [+4] '0' [+3] " brne loop%=\n\t" // '1' [+5] '0' [+4] : "=&d" (ctr) : "r" (curbyte), "x" (port), "r" (maskhi), "r" (masklo) ); } SREG = sreg_prev; } void ws2811_set_color(unsigned int r, unsigned int g, unsigned int b ) { uint8_t data[3] = {r, g, b}; ws2811_send_array(data, 3, pinMask, (uint8_t*)ws2812_port); } void ws2811_set_colors(uint8_t *data, uint8_t data_len) { ws2811_send_array(data, data_len, pinMask, (uint8_t*)ws2812_port); }
参考资料
WS2811资料 - http://www.world-semi.com/technology/details-106-4.html