ghost_d_oleg (ghost_d_oleg) wrote,
ghost_d_oleg
ghost_d_oleg

Category:

AVR HV Programmer Shield. Или неудачная попытка "оживить" Atmega48.


Так вышло, что мой приятель собирая схему управления ПК через ИК-порт, при прошивке Atmega48 (c помощью avrdude.exe) ошибся с установкой FUSE :).  Для прошивки мы использовали ICSP разъем платы Ардуино, вытащив родной контроллер и вставив подопытный. Благо, распиновка позволяла. 
И вот у нас на руках оказался "дохлый" МК. Поиски в инете привели к HV программатору. Ну и так, как на руках уже есть Arduino, то грех не воспользоваться.
Оригинал статьи тут.  Сразу скажу, наш контроллер "оживить" не удалось. То ли действительно контроллеру хана, то ли ошибки в коде... Так, что не спешите повторять схему. А если кто-то поможет в поисках ошибок - буду премного благодарен.


Собирать на макетке не хотелось, тем более, что вещь обещала быть достаточно полезным шилдом. Плюс еще купились на лестные отзывы об успешном восстановлении именно Atmega48. Схема, приведенная в статье, один в один совпадала с даташитом на данным микроконтроллер.  
Так к
ак у меня самодельный Ардуино, то для питания используется внешний БП на 12 вольт. А в шилде управление подачей +12В сделано через транзистор (в более продвинутом шилде применяют преобразователь 5в->12в).
Сказано - сделано.
Разводка, травление и запайка деталей заняла у нас около 2-х часов.
Делалось все быстро, и на "красоту" внимания не обращалось. Так, что не судите строго.






Для защиты выводов контроллера (на всякий случай) Все подключения через резисторы по 1 кОм.

Итак, для изготовления шилда нам понадобиться:
 -  резистор 1 кОм - 20 штук
 -  транзистор N-P-N (у меня был C945) - 1шт.
 - кнопка - 1 шт
 - светодиод - 1 шт
 - кусок текстолита 70х55 мм
 - колодка 28 ножек (узкая). У нас не оказалось, поэтому "сколхозили" из старых плат
 - штырьки для подключения к Ардуино

Вот схема:


Вот, что получилось на печатке:



Для простоты монтажа элементов, дорожки сверху. (печатка)

ЛУТом изготавливаем печатную плату.


Лудим, запаиваем элементы


Примеряемся к Ардуино

Так выглядит готовое устройство:



Теперь ПО. Приведенное у автора - убитый контроллер к жизни не вернуло. Начали разбираться, что же там делается. И ниже приведен код, с моими комментариями.
Добавлена процедура Chip ERASE. 


----------- кусать тут ----------
/*  
 HVFuse - Use High Voltage Programming Mode to Set Fuses on ATmega48/88/168
 09/23/08  Jeff Keyzer  http://mightyohm.com                
 The HV programming routines are based on those described in the
 ATmega48/88/168 datasheet 2545M-AVR-09/07, pg. 290-297
 This program should work for other members of the AVR family, but has only
 been verified to work with the ATmega168.  If it works for you, please
 let me know!  http://mightyohm.com/blog/contact/
--------------------------------------------------
Русские комментарии и изменения by Ghost D. 2012
 */
// Заводские значения Fuse
#define  HFUSE  0xDF   // Default for ATmega48/88/168, for others see
#define  LFUSE  0x62   // http://www.engbedded.com/cgi-bin/fc.cgi
//          Pin mapping, согласно даташиту
//          _____________
//  RDY  <-  |PD1    (3)    Pinы для Atmega 48/88/168
//  OE   ->  |PD2    (4)
//  WR   ->  |PD3    (5)
//  BS1  ->  |PD4    (6)
//  XA0  ->  |PD5    (11)
//  XA1  ->  |PD6    (12)
//  PAGEL->  |PD7    (13)
//  +12V ->  |RESET  (1)
//  BS2  ->  |PC2    (25)
//  _П_  ->  |XTAL1  (9)
//  GND  ->  |GND    (8,22)
//  +5V  ->  |VCC    (7)
//  +5V  ->  |AVCC   (20)
// DATA  ->  |PC[1:0]:PB[5:0] (14,15,16,17,18,19,23,24)
//
// Pin Assignments
#define  DATA    PORTD // PORTD = Arduino цифровые выводы 0-7
#define  DATAD   DDRD  // Data direction register for DATA port
#define  VCC     8
//#define  RDY     12     // RDY/!BSY сигнал от подопытного контроллера
#define  OE      11
#define  WR      10
#define  BS1     9
#define  XA0     13
#define  XA1     18    // Аналоговые входы 0-5 используем как цифровые выводы
#define  PAGEL   19    // с номерами 14-19
#define  RST     14    // вывод управления подачи +12В для !RESET
#define  BS2     16
#define  XTAL1   17
#define  BUTTON  15    // Отслеживание нажатия кнопки
void setup()  // Выполняется один раз при запуске
{
  DATA = 0x00;  // Очищаем цифровые выводы 0-7
  DATAD = 0xFF; // устанавливаем цифровые выводы 0-7 как outputs
  pinMode(VCC, OUTPUT);
//  pinMode(RDY, INPUT);
  pinMode(OE, OUTPUT);
  pinMode(WR, OUTPUT);
  pinMode(BS1, OUTPUT);
  pinMode(XA0, OUTPUT);
  pinMode(XA1, OUTPUT);
  pinMode(PAGEL, OUTPUT);
  pinMode(RST, OUTPUT);  // вывод для подачи  +12V !RESET (Он работает инверсно, т.е. 1 - транзистор открыт и на выходе - 0)
  pinMode(BS2, OUTPUT);
  pinMode(XTAL1, OUTPUT);
  pinMode(BUTTON, INPUT);
  digitalWrite(BUTTON, HIGH);  // 
  // 
  digitalWrite(RST, HIGH);  // Снимаем напряжение 12V
}
void loop()  // основной цикл
{
  while(digitalRead(BUTTON) == HIGH) {  // Ждем нажатия клавиши
  }
  // Процедура входа в режим программирования, см. стр. 291
  // Инициализация сигналов для входа в режим программирования
  // см. стр. 290 даташита
  digitalWrite(PAGEL, LOW);
  digitalWrite(XA1, LOW);
  digitalWrite(XA0, LOW);
  digitalWrite(BS1, LOW);
  delay(1);
  // Вход в режим программирования
   digitalWrite(VCC, HIGH);  // Подаем напряжение питания на "подопытный" контроллер
  delayMicroseconds(60);  //Задержка на 60 мс
  digitalWrite(WR, HIGH);  // Устанавливаем !OE and !WR
  digitalWrite(OE, HIGH); // если ОЕ - low- Data output
  digitalWrite(RST, LOW);   // Теперь подаем +12V
  // Теперь мы  находимся в режиме програмирования, пока не снимем напряжение +12В
 delayMicroseconds(300);
  
  // Попробуем выполнить Chip ERASE (стр. 292)
  sendcmd(B10000000);
  digitalWrite(WR, LOW);  // делаем отрицательный импульс для запуска стирания
  delay(1);
  digitalWrite(WR, HIGH);
  delay(10000);  // Задержка на 5 секунду
  // тут выставляем  HFUSE
  sendcmd(B01000000);  // Отправляем команду на программирование Fuse
  writefuse(HFUSE, true);
  // а тут программируем LFUSE
  sendcmd(B01000000);
  writefuse(LFUSE, false);
  
   // Все выполнене, прибираемся
  // Снимаем +12В, для выхода из режима программирования
  digitalWrite(RST, HIGH);
  // со всех выводов снимаем напряжения
  DATA = 0x00;
  digitalWrite(OE, LOW);
  digitalWrite(WR, LOW);
  digitalWrite(PAGEL, LOW);
  digitalWrite(XA1, LOW);
  digitalWrite(XA0, LOW);
  digitalWrite(BS1, LOW);
  digitalWrite(BS2, LOW);
  digitalWrite(VCC, LOW);
}
void sendcmd(byte command)  // Подпрограмма засылки команду в микроконтроллер
{
  // 
  digitalWrite(XA1, HIGH); //Согласно таб. 28-13 (стр. 291) 
  digitalWrite(XA0, LOW);  // ХА1=1 и ХА0=0 - загрузка команды
  digitalWrite(BS1, LOW);  // 
  DATA = command;          // на выводах устанавливаем значение команды
  digitalWrite(XTAL1, HIGH);  // делаем положительный импульс
  delay(1);
  digitalWrite(XTAL1, LOW);
  delay(1);
  
}
void writefuse(byte fuse, boolean highbyte)  // Запись fuse (Low и Hight)
{
  // Если highbyte = true, то программируем HFUSE, иначе LFUSE если BS1=1, то пишем HFUSE
  // Разрешаем загрузку данных
  digitalWrite(XA1, LOW); // ХА1=0 и ХА0=1 - загрузка данных
  digitalWrite(XA0, HIGH);
  delay(1);
  // пишем fuse
  DATA = fuse;  
  digitalWrite(XTAL1, HIGH); //делаем импульс
  delay(1);
  digitalWrite(XTAL1, LOW);
  if(highbyte == true)  
    digitalWrite(BS1, HIGH);  // program HFUSE
  else
    digitalWrite(BS1, LOW);
  digitalWrite(WR, LOW); // производим запись
  delay(1);
  digitalWrite(WR, HIGH);
  delay(100);
}

----------- кусать тут ----------




Tags: arduino, hv programer, shield, Очумелые ручки, своими руками
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments