Мне тут досталась для опытов одна atmega32, у которой фьюзы были установлены так, что она по SPI не программировалась и не отвечала вообще.
Собственно, так как с ней работали только через SPI, то очевидно, что проблема в источнике тактирования. Варианты все описаны в даташите.
Первым делом, я решим перепробовать все возможные варианты тактирования. Попробовал внешний кристалл, внешнюю RC цепь, попытался подать тактовый сигнал с другой атмеги – ничего не заработало. Остался только один вариант – это Low-frequency Crystal Oscillator. У меня его дома нет (хотя и зря).
Однако, коли я все равно питаю все свои схемы от компа, то я же могу завести с него и +12 и помощью atmega8 сделать параллельное программирование.
У atmega8 с учетом подключения LCD по 4-х битному интерфейсу, только только хватило ног.
PB с atmega8 полностью идет на PB atmega32 один в один
PD2-PD6 – на PD2-PD6
PD1 на XTAL1
PD7 на PA0
Получается вот такой расклад битов на PD у atmega8
#define X_XTAL1 1
#define X_OE 2
#define X_WR 3
#define X_BS1 4
#define X_XA0 5
#define X_XA1 6
#define X_BS2 7
RSY/BSY – подключен на GND через светодиод. Когда делается CHIP RESET, то он дергается.
PAGEL – кинуть на GND.
Провод +12 от компа идет на макетку. Суть такая, что по даташиту, надо дать на RESET atmega32 сначала GND, сделать некие манипуляции, после чего подать туда +12В. Поэтому на экране программа сначала говорит, что надо присоединить к GND, а потом, когда надо, пишет, что надо к +12В подсоединить. На практике, на GND не потребовалось сажать, можно сразу ткнуть на +12В и все работали и так.
Программный код работы с экраном приводить не буду – надо, найдете и замените вывод на LCD на свою любимую библиотеку.
Странное дело с таймингами. Atmega8 работает на 1МГц. Т.е. любая операция выполняется не менее 1мкс. Тайминги по параллельному программированию в основном – сотни наносекунд, но все меньше чем 1 мкс. Однако, если не делать задержек – НЕ РАБОТАЕТ. Странно, но факт.
При чтении фьюзов все совпало. Там как раз стоят исчточник тактирования - Low-frequency Crystal Oscillator.
Основной код, достаточный, чтобы сделать chip reset и сделать default fuses.
Исходник
Полный исходник с чтением signature и fuses (без либы для lcd): recover.c
Не помешало бы схему выложить.
Спасибо за девайс, восстановил 2 штуки убитых Atmega32.
Unlock somes atmega8.
Gracias!
From Mexico!
#define X_XTAL1 1
#define X_OE 2
#define X_WR 3
#define X_BS1 4
#define X_XA0 5
#define X_XA1 6
#define X_BS2 7
int main() {
DDRD|=0b11111110;
_delay_ms(5000);
// connect reset of bad chip to gnd now
// toggle xtal1 at lease 6 times
for(i=0;i<8;i++){
PORTD|=_BV(X_XTAL1);
_delay_ms(10);
PORTD&=~_BV(X_XTAL1);
_delay_ms(10);
}
// set prog enable pins (pagel is gnd, xa0, xa1, bs1 - zero)
// PD4,PD5,PD6
PORTD&=~(_BV(X_XA0)|_BV(X_XA1)|_BV(X_BS1));
PORTD|=_BV(X_WR); // write disables
_delay_ms(5000);
// connect reset of bad chip to +12 NOW
// SET OE HIGH
PORTD|=_BV(X_OE);
DDRB=0xff;
// chip erase
//Set XA1 to 1, XA0 to 0. This enables command loading.
PORTD|=_BV(X_XA1);
PORTD&=~_BV(X_XA0);
// Set BS1 to “0”, BS1 - PD4
PORTD&=~_BV(X_BS1);
// Set DATA to command
PORTB=0b10000000;
//Give XTAL1 a positive pulse. This loads the command., XTAL1 - PD1
PORTD|=_BV(X_XTAL1);_delay_ms(10);PORTD&=~_BV(X_XTAL1);_delay_ms(10);
// Give WR a negative pulse. This starts the Chip Erase. RDY/BSY goes low.
PORTD&=~_BV(X_WR);_delay_ms(10);PORTD|=_BV(X_WR);_delay_ms(10);
// wait a bit
_delay_ms(1000);
// load default data for FUSE low byte
//Set XA1 to 1, XA0 to 0. This enables command loading.
PORTD|=_BV(X_XA1);
PORTD&=~_BV(X_XA0);
// Set BS1 to “0”, BS1 - PD4
PORTD&=~_BV(X_BS1);
// Set DATA to command
PORTB=0b01000000;
//Give XTAL1 a positive pulse. This loads the command., XTAL1 - PD1
PORTD|=_BV(X_XTAL1);_delay_ms(10);PORTD&=~_BV(X_XTAL1);_delay_ms(10);
// load data
PORTD&=~_BV(X_XA1);
PORTD|=_BV(X_XA0);
PORTB=0b11100001; // DEFAULT VALUE FOR LOW FUSE BYTE
PORTD|=_BV(X_XTAL1);_delay_ms(10);PORTD&=~_BV(X_XTAL1);_delay_ms(10);
// Set BS1 to “0” and BS2 to “0”.
PORTD&=~_BV(X_BS1);
PORTD&=~_BV(X_BS2);
// Give WR a negative pulse. This starts the Chip Erase. RDY/BSY goes low.
PORTD&=~_BV(X_WR);_delay_ms(10);PORTD|=_BV(X_WR);_delay_ms(10);
// load default data for HIGH low byte
//Set XA1 to 1, XA0 to 0. This enables command loading.
PORTD|=_BV(X_XA1);
PORTD&=~_BV(X_XA0);
// Set BS1 to “0”, BS1 - PD4
PORTD&=~_BV(X_BS1);
// Set DATA to command
PORTB=0b01000000;
//Give XTAL1 a positive pulse. This loads the command., XTAL1 - PD1
PORTD|=_BV(X_XTAL1);_delay_ms(10);PORTD&=~_BV(X_XTAL1);_delay_ms(10);
// load data
PORTD&=~_BV(X_XA1);
PORTD|=_BV(X_XA0);
PORTB=0b10011001; // DEFAULT VALUE FOR HIGH FUSE BYTE
PORTD|=_BV(X_XTAL1);_delay_ms(10);PORTD&=~_BV(X_XTAL1);_delay_ms(10);
// Set BS1 to “0” and BS2 to “0”.
PORTD|=_BV(X_BS1);
PORTD&=~_BV(X_BS2);
// Give WR a negative pulse. This starts the Chip Erase. RDY/BSY goes low.
PORTD&=~_BV(X_WR);_delay_ms(10);PORTD|=_BV(X_WR);_delay_ms(10);
// done
while(1);
}
Странная просьба какая-то.
См а) даташит б) описание в) видео, если ничего не поможет, то ничего не поможет.
Thanks sir
green.bamboo.sg@gmail.com
Googdle transaltes very well
PB matched PB on atmega32
PD2-PD6 – to PD2-PD6
PD1 to XTAL1
PD7 to PA0
Pay attention, think, read datasheet. Don't be lazy.