Последние пару вечеров глажу, отмачиваю, лужу, паяю, в основном микроплатки со светодиодами; вчера случился эпик фейл с большой платой, которая будет обслуживать 9 источников света: накатал, отмочил бумагу, перенесся рисунок просто идеально; вытравил, насверлил дырок, начал «примеряться» и только тут увидел, что что-то не так
Забыл отзеркалить плату перед печатью, соотв. она получилась неправильно.. фуцк, что тут еще сказать..
Сегодня повторю процесс, воспользовался случаем чтобы улучшить кое-что на плате
Схема пока такая:

примерная схема для отладки

плата такая пока получается
Раз плату переделывать – так добавил пинов, чтобы подпаивать jtag да программатор
Схема рисовалась в угоду плате, поэтому светодиоды подключаются черти-как, надеюсь, что проблем с этим не будет. Соорудил изящную (для моего знания си) конструкцию: в hardware.h (в этом файле собрано все, что касается конкретной железяки) описываю подключение примерно так:
#define L1_R PORTB, 2
#define L1_G PORTB, 1
#define L1_B PORTB, 0
#define L2_R PORTB, 5
#define L2_G PORTB, 4
#define L2_B PORTB, 3
что, кстати, уже не соотвествует реалиям – микроплатки для светодиодов то у меня тоже «зеркальные», это не мешает им светится, но R и B каналы по идее попутаны; потом придумал макрос
#define set(x,p) ((x)?(sbi(p)):(cbi(p)))
чтобы в прерывании, где программный ШИМ зажигает «лампочки» просто написать:
ISR(TIMER0_OVF_vect)
{
u08 * value;
value = &data[0]; // 'то начало массива, где хранятся rgb-значения
set((*value++) > counter, L1_R);
set((*value++) > counter, L1_G);
set((*value++) > counter, L1_B);
set((*value++) > counter, L2_R);
set((*value++) > counter, L2_B);
set((*value++) > counter, L2_G);
set((*value++) > counter, L3_R);
...
Т.е. в зависимости от того, пора включить или выключить светодиод будет устанавливаться или сниматься пин на порту соответствующем; плюс вроде в том, что если поменяется «распиновка» (вот как у меня случилось), так я просто в define поменяю цифирки; второй плюс (вроде.. мне просто лень сделать по другому и сравнить результат) – установка/снятие бита делается одной ассемблерной командой, так что это вроде должно быть ненапряжно:
u08 * value;
value = &data[0];
set((*value++) > counter, L1_R);
de: 80 91 60 00 lds r24, 0x0060
e2: 90 91 8a 00 lds r25, 0x008A
e6: 98 17 cp r25, r24
e8: 10 f4 brcc .+4 ; 0xee <__vector_9+0x1e>
ea: c2 9a sbi 0x18, 2 ; 24
ec: 01 c0 rjmp .+2 ; 0xf0 <__vector_9+0x20>
ee: c2 98 cbi 0x18, 2 ; 24
f0: 88 b3 in r24, 0x18 ; 24
set((*value++) > counter, L1_G);
f2: 80 91 61 00 lds r24, 0x0061
f6: 98 17 cp r25, r24
f8: 10 f4 brcc .+4 ; 0xfe <__vector_9+0x2e>
fa: c1 9a sbi 0x18, 1 ; 24
fc: 01 c0 rjmp .+2 ; 0x100 <__vector_9+0x30>
fe: c1 98 cbi 0x18, 1 ; 24
100: 88 b3 in r24, 0x18 ; 24