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
