Преамбула.
Купил в Китае партейку Attiny13a, в количестве 10шт. Беру довольный один из контроллеров, чтобы вставить в проект, что давно запланировал... А запрограммировать контроллер не получается. Облом на стадии чтения сигнатуры "avrdude: Device signature = 0xffffff". Перепробовал все подряд, но ни на грамм... Купил, в 5 раз (только вдумаемся в 5 раз!!!) дороже за контроллер, пару контроллеров в "Чип и Дип" (выручает, конечно, когда срочно надо, но блин цены). Проверяю новые, а они прекрасно пашут как надо, на них я и реализовал свой проект.
Амбула.
Купленная партия мне по прежнему не давала покоя! Или ее выкинуть или как-то оживить. Бракованная партия или нет?
Последнее средство - это "High-Voltage Serial Programming".
Решил поискать средства, как это можно сделать. Сперва наткнулся на вариант программатора http://www.rlocman.ru/shem/schematics.html?di=105713 - все супер и я уже почти было взялся его собрать, но, в процессе подготовки, нашел вариант проще:
http://habrahabr.ru/post/249967/.
Для истории, необходимо подключить МК по следующей схеме:

К Arduino, в которую надо залить прошивку...
А вот с прошивка будет чуть позже.
ВНИМАНИЕ!!!
Стоит упомянуть, что нужно соблюдать повышенную осторожность при подключении 12 В части, потому, что это напряжение запросто палит как микроконтроллеры так и другую периферию Arduino, например преобразователь USB-TTL. Поэтому следуем алгоритму:
- Собираем схему;
- Подаем питание на Arduino подключив к юсб;
- Подаём +12В на транзистор;
- Восстанавливаем микроконтроллер;
- Отключаем +12В.
Я воспользовался предоставленной прошивкой в теме, НО... Прочитать контроллер получилось, т.е. они работают! А записать новые фьюзы никак. Прочитал, что если есть проблемы с записью, то значит есть проблемы с питанием МК. Замкнул питание напрямую, без страховочного резистора, но нет. Читать - читает, но не пишет.
Ответ нашелся неожиданно. Сперва надо сделать очистку МК - Chip Erase. Изучив код восстановителя фьюзов и почитав datasheet, я добавил в программатор функцию очистки (далее код для arduino в роли программатора):
Код: Выделить всё
// AVR High-voltage Serial Fuse Reprogrammer
// Adapted from code and design by Paul Willoughby 03/20/2010
// http://www.rickety.us/2010/03/arduino-avr-high-voltage-serial-programmer/
//
// Fuse Calc:
// http://www.engbedded.com/fusecalc/
#define RST 13 // Output to level shifter for !RESET from transistor
#define SCI 12 // Target Clock Input
#define SDO 11 // Target Data Output
#define SII 10 // Target Instruction Input
#define SDI 9 // Target Data Input
#define VCC 8 // Target VCC
#define HFUSE 0x747C
#define LFUSE 0x646C
#define EFUSE 0x666E
// Define ATTiny series signatures
#define ATTINY13 0x9007 // L: 0x6A, H: 0xFF 8 pin
#define ATTINY24 0x910B // L: 0x62, H: 0xDF, E: 0xFF 14 pin
#define ATTINY25 0x9108 // L: 0x62, H: 0xDF, E: 0xFF 8 pin
#define ATTINY44 0x9207 // L: 0x62, H: 0xDF, E: 0xFFF 14 pin
#define ATTINY45 0x9206 // L: 0x62, H: 0xDF, E: 0xFF 8 pin
#define ATTINY84 0x930C // L: 0x62, H: 0xDF, E: 0xFFF 14 pin
#define ATTINY85 0x930B // L: 0x62, H: 0xDF, E: 0xFF 8 pin
void setup() {
pinMode(VCC, OUTPUT);
pinMode(RST, OUTPUT);
pinMode(SDI, OUTPUT);
pinMode(SII, OUTPUT);
pinMode(SCI, OUTPUT);
pinMode(SDO, OUTPUT); // Configured as input when in programming mode
digitalWrite(RST, HIGH); // Level shifter is inverting, this shuts off 12V
Serial.begin(19200);
}
void loop() {
if (Serial.available() > 0) {
Serial.read();
pinMode(SDO, OUTPUT); // Set SDO to output
digitalWrite(SDI, LOW);
digitalWrite(SII, LOW);
digitalWrite(SDO, LOW);
digitalWrite(RST, HIGH); // 12v Off
digitalWrite(VCC, HIGH); // Vcc On
delayMicroseconds(20);
digitalWrite(RST, LOW); // 12v On
delayMicroseconds(10);
pinMode(SDO, INPUT); // Set SDO to input
delayMicroseconds(300);
unsigned int sig = readSignature();
Serial.print("Signature is: ");
Serial.println(sig, HEX);
readFuses();
if (sig == ATTINY13) { // Только для тини13 добавлена очистка контроллера!
ChipErase (); // Очистка памяти контроллера перед установкой фьюзов
Serial.print("write LFuse: ");
Serial.print(0x6A, HEX); //Выводим что хотим записать
writeFuse(LFUSE, 0x6A); //Пишем фьюзы
Serial.print(", HFuse: ");
Serial.println(0xFF, HEX); //Выводим что хотим записать
writeFuse(HFUSE, 0xFF); //Пишем фьюзы
} else if (sig == ATTINY24 || sig == ATTINY44 || sig == ATTINY84 ||
sig == ATTINY25 || sig == ATTINY45 || sig == ATTINY85) {
writeFuse(LFUSE, 0x62);
writeFuse(HFUSE, 0xDF);
writeFuse(EFUSE, 0xFF);
}
readFuses();
digitalWrite(SCI, LOW);
digitalWrite(VCC, LOW); // Vcc Off
digitalWrite(RST, HIGH); // 12v Off
}
}
byte shiftOut (byte val1, byte val2) {
int inBits = 0;
//Wait until SDO goes high
while (!digitalRead(SDO))
;
unsigned int dout = (unsigned int) val1 << 2;
unsigned int iout = (unsigned int) val2 << 2;
for (int ii = 10; ii >= 0; ii--) {
digitalWrite(SDI, !!(dout & (1 << ii)));
digitalWrite(SII, !!(iout & (1 << ii)));
inBits <<= 1;
inBits |= digitalRead(SDO);
digitalWrite(SCI, HIGH);
digitalWrite(SCI, LOW);
}
return inBits >> 2;
}
void ChipErase () { // Добавленная функция очистки контроллера
shiftOut(0x80, 0x4C);
shiftOut(0x00, 0x64);
shiftOut(0x00, 0x6C);
}
void writeFuse (unsigned int fuse, byte val) {
shiftOut(0x40, 0x4C);
shiftOut( val, 0x2C);
shiftOut(0x00, (byte) (fuse >> 8));
shiftOut(0x00, (byte) fuse);
}
void readFuses () {
byte val;
shiftOut(0x04, 0x4C); // LFuse
shiftOut(0x00, 0x68);
val = shiftOut(0x00, 0x6C);
Serial.print("LFuse: ");
Serial.print(val, HEX);
shiftOut(0x04, 0x4C); // HFuse
shiftOut(0x00, 0x7A);
val = shiftOut(0x00, 0x7E);
Serial.print(", HFuse: ");
Serial.print(val, HEX);
shiftOut(0x04, 0x4C); // EFuse
shiftOut(0x00, 0x6A);
val = shiftOut(0x00, 0x6E);
Serial.print(", EFuse: ");
Serial.println(val, HEX);
}
unsigned int readSignature () {
unsigned int sig = 0;
byte val;
for (int ii = 1; ii < 3; ii++) {
shiftOut(0x08, 0x4C);
shiftOut( ii, 0x0C);
shiftOut(0x00, 0x68);
val = shiftOut(0x00, 0x6C);
sig = (sig << 8) + val;
}
return sig;
}
