-
Залоченный ATMega8 RSTDISBL: решение старой проблемы
-
ATMega8
Иногда случается по невнимательности во время программирования Mega8 случайно записать фюзы с выставленным в 1 битом RSTDISBL. В результате такой оплошности ножка RESET переключается в режим обычного порта ввода-вывода и микроконтроллер больше не хочет программироваться "последовательными" программаторами.
Решение проблемы очень простое: надо просто вернуть бит RSTDISBL в исходное состояние. Но, к сожалению, сделать это можно только с помощью "параллельного" программатора.
Если под рукой есть еще один рабочий микроконтроллер (в моём случае это был Mega32), макетная плата и немного проводков, то за 20 минут процессор можно вернуть к жизни.
Ниже приведена принципиальная схема, на которой показано соединение рабочей Mega32 и впавшей в кому Mega8.
Схема соединений ATMega32 и ATMega8 с залоченным RSTDISBL
Принципиальная схема в формате Splan7
Привожу исходный код лечащей программы. Как можно заметить, программа написана на простом С. Я компилировал это в IAR Embedded Workbench for Atmel. Поскольку код очень простой, не составит поправить заголовки под любую другую среду разработки. Так-же несложно переписать код для работы с другим процессором, например Mega8.
Следует иметь ввиду, что перед тем, как записать "правильные" фюзы в микроконтроллер происходит предварительное выполнение команды "Chip erase". В результате этого всё содержимое памяти программ микроконтроллера стирается. Делается это затем, что микросхема может оказаться не только со сброшенным битом RSTDISBL, но и с выставленной защитой от записи-считывания. Поэтому лучше сначала подстраховаться при помощи команды "Chip erase", сбросив биты защиты.
В схеме стоит кварцевый резонатор на 11,0592 MHz. Вместо него можно использовать любой другой, имеющийся под рукой или использовать тактование от внутреннего генератора. Надо только не забыть соответственно поправить заголовочный файл main.h так, чтоб задержкт рассчитывались с учётом изменившейся тактовой частоты.
Для этого надо в строке
#define F_CPU 11059200UL
переопределить F_CPU, подставив своё значение частоты в герцах.
#include "pin_macros.h" #include <iom32.h> #include <pgmspace.h> #include <stdlib.h> #include <pgmspace.h> #include <inavr.h> #include "main.h" #define nOE 0 // B0 #define nWR 1 // B1 #define BS1 2 // B2 #define XA0 3 // B3 #define XA1 4 // B4 #define RDY 0 // C0 #define XTAL1 1 // C1 #define BS2 2 // C2 #define PAGEL 3 // C3 #define nPROG 4 // C4 #define nLED 5 // C5 void XtalPulse(void); //--------------------------------------------------------------------------- int main() { DDRA = 0xFF; // Data port is Output DDRB = (1<<XA1) | (1<<XA0) | (1<<BS1) | (1<<nWR) | (1<<nOE); DDRC = (1<<nLED) | (1<<nPROG) | (1<<PAGEL) | (1<<BS2) | (1<<XTAL1); PORTA = 0x00; PORTB = (1<<nWR); PORTC = 0x01; SetBit(PORTC, nLED); _delay_us(100); //===== Stage 1 - Chip Erase ===== ClearBit(PORTB, XA0); // Set XA1, XA0 to “10”. This enables command loading SetBit(PORTB, XA1); ClearBit(PORTB, BS1); // Set BS1 to “0” ClearBit(PORTC, BS2); PORTA = 0x80; // Load "Chip Erase" command XtalPulse(); // Give XTAL1 a positive pulse. This loads the command _delay_us(10); ClearBit(PORTB, nWR); // Give WR a negative pulse. This starts the Chip Erase. RDY/BSY goes low _delay_us(10); SetBit(PORTB, nWR); do { _delay_us(10); } while( !(PINC & (1<<RDY)) ); // Wait until RDY/BSY goes high //====== Stage 2 - Write FUSE Low Byte ====== ClearBit(PORTB, XA0); // Set XA1, XA0 to “10”. This enables command loading SetBit(PORTB, XA1); ClearBit(PORTB, BS1); // Set BS1 to “0” ClearBit(PORTC, BS2); // Set BS2 to “0” PORTA = 0x40; // Load "Write FUSE" command XtalPulse(); // Give XTAL1 a positive pulse. This loads the command SetBit(PORTB, XA0); // Set XA1, XA0 to “01”. This enables data loading ClearBit(PORTB, XA1); // (High or Low data byte for Flash determined by BS1) ClearBit(PORTB, BS1); // Set BS1 to “0” - Low byte ClearBit(PORTC, BS2); // Set BS2 to “0” PORTA = 0xE1; // 0b11100001 BODLEVEL BODEN SUT1 SUT0 CKSEL3 CKSEL2 CKSEL1 CKSEL0 XtalPulse(); ClearBit(PORTB, BS1); // Set BS1 to “0” - Low byte ClearBit(PORTC, BS2); // Set BS2 to “0” ClearBit(PORTB, nWR); // Give WR a negative pulse. This starts the Chip Erase. RDY/BSY goes low _delay_us(10); SetBit(PORTB, nWR); do { _delay_us(10); } while( !(PINC & (1<<RDY)) ); // Wait until RDY/BSY goes high //===== Stage 3 - Write FUSE High Byte ====== ClearBit(PORTB, XA0); // Set XA1, XA0 to “10”. This enables command loading SetBit(PORTB, XA1); ClearBit(PORTB, BS1); // Set BS1 to “0” - Low byte ClearBit(PORTC, BS2); // Set BS2 to “0” PORTA = 0x40; // Load "Write FUSE" command XtalPulse(); // Give XTAL1 a positive pulse. This loads the command SetBit(PORTB, XA0); // Set XA1, XA0 to “01”. This enables data loading ClearBit(PORTB, XA1); // (High or Low data byte for Flash determined by BS1) ClearBit(PORTB, BS1); // Set BS1 to “0” - Low byte ClearBit(PORTC, BS2); // Set BS2 to “0” PORTA = 0xD9; // 0b11011001 ;(RSTDISBL WDTON SPIEN CKOPT EESAVE BOOTSZ1 BOOTSZ0 BOOTRST) XtalPulse(); SetBit(PORTB, BS1); // Set BS1 to “1” - High byte ClearBit(PORTC, BS2); // Set BS2 to “0” ClearBit(PORTB, nWR); // Give WR a negative pulse. This starts the Chip Erase. RDY/BSY goes low _delay_us(10); SetBit(PORTB, nWR); do { _delay_us(10); } while( !(PINC & (1<<RDY)) ); // Wait until RDY/BSY goes high ClearBit(PORTC, nLED); for(;;); } void XtalPulse(void) { _delay_us(10); SetBit(PORTC, XTAL1); _delay_us(10); ClearBit(PORTC, XTAL1); _delay_us(10); }
#ifndef MAIN_H #define MAIN_H #define F_CPU 11059200UL #define _delay_us(temp)(__delay_cycles((temp * F_CPU)/1000000UL)); #define ClearBit(reg, bit) reg &= ~(1<<(bit)) #define SetBit(reg, bit) reg |= (1<<(bit)) #define FlipBit(reg, bit) reg ^= (1<<(bit)) #endif
Прошивка
Версия 1.0.0 (26.09.2021)
Прошивка для процессора Mega32 с внешним кварцем на 4MHz. Версия 1.0: (доступно зарегистрированным пользователям)
- Войдите или зарегистрируйтесь, чтобы отправлять комментарии
ОБСУЖДЕНИЯ
как посмотреть принципиальные схемы
Мага
Принципиальная схема приведена в статье. Ничего другого нет.
здравствуйте вы не можете прислать прошивку?в статье я не нашол спасибо зарание.
Мага
К сожалению, файла с прошивкой не осталось. Есть только исходный код, котороый в статье. Я попробую сделать прошивку, но не обещаю. Если получится - выложу в на выходных.
спасибо буду очень рад.
Мага
Возьмите прошивку в конце статьи
Спасибо большое вам эта прошивка на мега 8 не подойтет?
Мага
Не пойдет, там нет порта A, который используется
спасибо буду искать мегу 32 или же схему на атмега 8.
Мага