Тема для обсуждения Параллельный прогромматор

Dmti
Dmti аватар
Offline
Зарегистрирован: 13.10.2013

Попался сайт с описанием параллельного прогромматора. Скопировал текст с сайта (он в виде каментария) и наскорую руку набросал основу, не доконца. Собирать даже не пытался. Выслушаю любые мнения.

/*Содрал с сайта http://radioelectronika.ru/?mod=cxemi&sub_mod=full_cxema&id=481
и отсюда http://usbsergdev.narod.ru/DOC/ATmega128rus.pdf
Проба собрать из ардуина паралельный прогроматор, потом. А пока востановитель фюзов 
думаю многим пригодится. Все изменения дополнения и улучшения прошу выкладывать на
форуме.
//*/
//************ноги***************************************************************ATmega8
const int RdyBsy = 1;//Состояние устройства 0-занято, 1-готово к приёму команды  //PD1
const int OE = 2;    //Управление шины данных РВ7..РВ0 0-выход, 1-вход           //PD2
const int WR = 3;    //Сигнал записи активный 0                                  //PD3
const int BS1 = 4;   //Выбор байта 0-младший, 1-старший                          //PD4
const int XA0 = 5;   //00-загрузка адреса, 01-загрузка данных                    //PD5
const int XA1 = 6;   //10-загрузка команды, 11-режим ожидания                    //PD6
const int PAGEL = 7; //Сигнал загрузки страницы памяти                           //PD7
const int BS2 = 8;   //Выбор байта 0-младший, 1-старший                          //PC2
const int PBD0 = 9;  //                                                          //PC0
const int PBD1 = 10; //                                                          //PC1
const int PBD2 = 11; //                                                          //PB0
const int PBD3 = 12; //Двунаправленная 8-ми разрядная                            //PB1
const int PBD4 = 13; //            шина данных                                   //PB2
const int PBD5 = 14; //                                                          //PB3
const int PBD6 = 15; //                                                          //PB4
const int PBD7 = 16; //                                                          //PB5
const int Vpp = 17;  //12v перевод в режим паралельного прогр.                   //RESET
const int RESET = 18;//Программный ресет  (подключен через диод)                 //RESET
const int XTAL1 = 19;//Вход тактого генератора                                   //XLAT1
const int Un = 20;   //Включение питания                                          //+5v
//GND
//Фюзы   (заводские настройки) //фюзы описывать не буду  
//                             //номера битов
boolean Lock1 = true;          //
boolean Lock2 = true;          //
boolean BootLock01 = true;     //
boolean BootLock02 = true;     //
boolean BootLock11 = true;     //
boolean BootLock12 = true;     //
boolean BOOTRST = true;        //H0
boolean BOOTSZ0 = true;        //H1
boolean BOOTSZ1 = false;       //H2
boolean EESAVE = true;         //H3
boolean CKOPT = true;          //H4
boolean SPIEN = false;         //H5
boolean WDTON = true;          //H6
boolean RSTDISBL = true;       //H7
boolean CKSEL0 = false;        //M0
boolean CKSEL1 = false;        //M1
boolean CKSEL2 = true;         //M2
boolean CKSEL3 = false;        //M3
boolean SUT0 = false;          //M4
boolean SUT1 = true;           //M5
boolean BODEN = true;          //M6
boolean BODLEVEL = true;       //M7
const int FuseL=228, FuseH = 219, FuseS; //Слова конфигурации младших, старших и защиты
      int fusel, fuseh, fuses;           //для чтения и изменений фюзов

//*******************************************************************************
void setup() {                
  //ноги на выход
  SetupPin();
  Serial.begin(9600);
  while (!Serial) {
    ; // void setup капирнул из примера
  }
}

//******************************************************************************
void loop() {
  int inByte;
  if (Serial.available() > 0) {
    // чтение из порта тоже скапировал из примера
    inByte = Serial.read();}
 //Сильно не заморачиваясь делаю контроль над прогроматором
 switch(inByte){
   case 1: //перводим камень в режим прогромирования
         {if(inizial()) PortPrint(inByte);
           else Eror(1);}
   case 2: //Чмтаем состояние
         {if(reads()) PortPrint(2);
           else Eror(2);}
   case 3: //Стираем
         {if(erase()) PortPrint(3);
           else Eror(3);}
   case 4: // и отключаем защиту
         {if(securiti()) PortPrint(4);
           else Eror(4);}
   case 5: //Востанавливаем фюзы
         {if(writef()) PortPrint(5);
           else Eror(5);}
 }//При необходимоти мохно добавить ещё действий
}
//******************************************************************************
boolean inizial()
{
// Перевод микроконтроллера в режим параллельного программирования:
//Обычный алгоритм такого перевода для микроконтроллера ATmega8 заключается в следующем:
//— подать напряжение 4,5...5,5 В на вывод +5V программируемого микроконтроллера и   
//выдержать паузу не менее 100 мкс;
digitalWrite(Un, HIGH);
delay(100);
//-   при   низком   уровне   на линии RESET подать не менее шести импульсов высокого уровня на линию XTAL1;
digitalWrite(RESET, LOW);
Pulse(6,XTAL1);
//— установить на линиях PAGEL, XA1, ХАО, BS1 состояние 0000 и выдержать паузу не менее 100 не;
digitalWrite(PAGEL, LOW);
digitalWrite(XA1, LOW);
digitalWrite(XA0, LOW);
digitalWrite(BS1, LOW); 
delay(100);
//— подать на линию RESET напряжение + 11,5...12,5 В. Микроконтроллер готов к параллельному программированию.
digitalWrite(Vpp, HIGH);
if(analogRead(RdyBsy)) return true; 
SetupPin();
//      Однако этот алгоритм неприменим, если у микроконтроллера запрограммирован разряд RSTDISBL или задан 
//   режим работы его тактового генератора 
//   с кварцевым резонатором либо с внешней RC-цепью. В этом случае используют другой алгоритм:
//— установить на линиях PAGEL, XA1, ХАО, BS1 состояние 0000;
digitalWrite(PAGEL, LOW);
digitalWrite(XA1, LOW);
digitalWrite(XA0, LOW);
digitalWrite(BS1, LOW); 
//— одновременно подать напряжение +4,5...5,5 В на линию +5Уи+11,5.. .12,5В на линию RESET;
digitalWrite(Vpp, HIGH);
digitalWrite(Un, HIGH);
//— выдержать паузу не менее 100 не;
delay(100);
//— если в микроконтроллере была включена защита памяти от считывания, отключить ее (одновременно стирается все 
//содержимое памяти);

//— восстановить состояние разряда RSTDISBL в старшем байте конфигурации и при необходимости разрядов

//CKSELO—CKSEL3 в младшем байте конфигурации;
//— выйти из режима программирования, установив низкий уровень на линии RESET.
//Техническое описание микроконтроллера рекомендует для дальнейшей работы войти в режим параллельного 
//программирования заново, используя первый из описанных алгоритмов.
if(analogRead(RdyBsy)) return true; 
else return false;
}

//*********************************************************************************************************
boolean reads()
{
//— Считывание конфигурации микроконтроллера ATmega8:
//— установить на линиях ХА1 и ХАО состояние 10, разрешающее загрузку команды;
digitalWrite(XA1, HIGH);
digitalWrite(XA0, LOW);
//— установить на линии BS1 низкий уровень;
digitalWrite(BS1, LOW);
//— установить линии D7—DO в состояние 01000000 (40Н);
digitalWrite(PBD7, LOW);
digitalWrite(PBD6, HIGH);
digitalWrite(PBD5, LOW);
digitalWrite(PBD4, LOW);
digitalWrite(PBD3, LOW);
digitalWrite(PBD2, LOW);
digitalWrite(PBD1, LOW);
digitalWrite(PBD0, LOW);
//— подать на линию XTAL1 импульс высокого уровня;
Pulse(1,XTAL1);
//— установить на линиях ОЕ, BS2, BS1 низкие уровни;
digitalWrite(OE, LOW);
digitalWrite(BS1, LOW);
digitalWrite(BS2, LOW);
//— прочитать на линиях D7—DO младший байт конфигурации;
fusel = LoadInt();
//— установить на линии ОЕ низкий, а на линиях BS2, BS1 высокие уровни;
digitalWrite(OE, LOW);
digitalWrite(BS1, HIGH);
digitalWrite(BS2, HIGH);
//— прочитать на линиях D7—DO старший байт конфигурации;
fuseh = LoadInt();
//— установить на линиях ОЕ, BS2 низкие, а на линии BS1 высокий уровни;
digitalWrite(OE, LOW);
digitalWrite(BS1, HIGH);
digitalWrite(BS2, LOW);
//— прочитать на линиях D7—DO байт защиты памяти;
fuses = LoadInt();
//— установить на линии ОЕ высокий уровень.
digitalWrite(OE, HIGH);
  return true;
}

//*********************************************************************************************************
boolean erase()
{
//      Стирание памяти и отключение ее защиты:
//— установить на линиях ХА1 и ХАО состояние 10, разрешающее загрузку команды;
//- установить низкий уровень на линии BS1;
//— установить линии D7—DO в состояние 10000000 (80Н), соответствующее команде стирания (Chip Erase);
//— подать на линию XTAL1 импульс высокого уровня для загрузки команды в микроконтроллер;
//— подать на линию WR импульс низкого уровня для выполнения стирания, при этом высокий уровень на 
//линии RDY/BSYсменится низким;
//— дождаться восстановления высокого уровня на линии RDY/BSY
  return true;
}

//*********************************************************************************************************
boolean securiti()
{
  return true;
}

//*********************************************************************************************************
boolean writef()
{
//Запись младшего байта конфигурации:
//— установить линии ХА1 и ХАО в состояние 10, разрешающее загрузку команды;
//— установить на линии BS1 низкий уровень;
//— установить линии D7—DO в состояние 01000000 (40Н), соответствующее   команде   записи   конфигурации 
//(Write Fuse Bits);
//— подать на линию XTAL1 импульс высокого уровня;
//— установить линии ХА1 и ХАО в состояние 01, соответствующее загрузке данных;
//— установить линии D7—DO в состояние 11100001 (ОЕ1Н, значение младшего байта конфигурации, устанавливаемое 
//при изготовлении микроконтроллера);
//— подать на линию XTAL1 импульс высокого уровня для загрузки данных;
//— установить линии BS2 и BS1 в состояние 00, соответствующее выбору младшего байта конфигурации;
//— подать на линию WR импульс низкого уровня и ждать появления высокого уровня на линии RDY/BSY

//Запись старшего байта конфигурации:
//— установить линии ХА1   и ХАО в состояние 10, разрешающее загрузку команды;
//— установить на линии BS1 низкий уровень;
//— установить линии D7—DO в состояние 01000000 (40Н);
//— подать на линию XTAL1 импульс высокого уровня;
//— установить линии ХА1 и ХАО в состояние 01, соответствующее загрузке данных;
//— установить линии D7—DO в состояние   11011001   (OD9H,   значение старшего байта конфигурации, 
//задаваемое при изготовлении микроконтроллера; важно установить 1 в разряде D7 (RSTDISBL), а в разряде 
//D5 (SPIEN) — О, разрешающий последовательное программирование;
//— подать на линию XTAL1 импульс высокого уровня;
//— установить на линиях BS2 и BS1 состояние 01, соответствующее выбору старшего байта конфигурации;
//— подать на линию WR импульс низкого уровня и ждать появления высокого уровня на линии RDY/BSY;
//— установить на линии BS1 низкий уровень.
  return true;
}

//*********************************************************************************************************
void PortPrint(int a)
{
  //return true;
}

//*********************************************************************************************************
void Eror(int a)
{
  //return true;
}

//*********************************************************************************************************
boolean Pulse(int a, int led)
{
  for(int i; i<a; i++){
  digitalWrite(led, HIGH);
  delay(5);
  digitalWrite(led, LOW);
  delay(5);}
}

//*********************************************************************************************************
void SetupPin ( void)
{
  pinMode(OE, OUTPUT);    digitalWrite(OE, LOW); 
  pinMode(WR, OUTPUT);    digitalWrite(WR, LOW);
  pinMode(BS1, OUTPUT);   digitalWrite(BS1, LOW); 
  pinMode(BS2, OUTPUT);   digitalWrite(BS2, LOW);
  pinMode(XA0, OUTPUT);   digitalWrite(XA0, LOW);
  pinMode(XA1, OUTPUT);   digitalWrite(XA1, LOW);
  pinMode(PAGEL, OUTPUT); digitalWrite(PAGEL, LOW);
  pinMode(PBD0, OUTPUT);  digitalWrite(PB0, LOW); 
  pinMode(PBD1, OUTPUT);  digitalWrite(PB1, LOW); 
  pinMode(PBD2, OUTPUT);  digitalWrite(PB2, LOW); 
  pinMode(PBD3, OUTPUT);  digitalWrite(PB3, LOW); 
  pinMode(PBD4, OUTPUT);  digitalWrite(PB4, LOW); 
  pinMode(PBD5, OUTPUT);  digitalWrite(PB5, LOW); 
  pinMode(PBD6, OUTPUT);  digitalWrite(PB6, LOW); 
  pinMode(PBD7, OUTPUT);  digitalWrite(PB7, LOW); 
  pinMode(Vpp, OUTPUT);   digitalWrite(Vpp, LOW); 
  pinMode(XTAL1, OUTPUT); digitalWrite(XTAL1, LOW); 
}

//*********************************************************************************************************
int LoadInt(void)
{
int Fuse =analogRead(PBD0)<<0|
          analogRead(PBD1)<<1|
          analogRead(PBD2)<<2|
          analogRead(PBD3)<<3|
          analogRead(PBD4)<<4|
          analogRead(PBD5)<<5|
          analogRead(PBD6)<<6|
          analogRead(PBD7)<<7; 
 return Fuse;
}

//*********************************************************************************************************
void SaveInt(int Data)
{
           digitalWrite(PBD0, Data<<0);
           digitalWrite(PBD0, Data<<1);
           digitalWrite(PBD0, Data<<2);
           digitalWrite(PBD0, Data<<3);
           digitalWrite(PBD0, Data<<4);
           digitalWrite(PBD0, Data<<5);
           digitalWrite(PBD0, Data<<6);
           digitalWrite(PBD0, Data<<7);
}

 

Dmti
Dmti аватар
Offline
Зарегистрирован: 13.10.2013
Маленько дополнил и исправил.

/*Содрал с сайта http://radioelectronika.ru/?mod=cxemi&sub_mod=full_cxema&id=481
и отсюда http://usbsergdev.narod.ru/DOC/ATmega128rus.pdf
Проба собрать из ардуина параллельный программатор, потом. А пока восстановитель фюзов 
думаю многим пригодится. Все изменения дополнения и улучшения прошу выкладывать на
форуме.
//*/
//************ноги***************************************************************ATmega8
const int RdyBsy = 1;//Состояние устройства 0-занято, 1-готово к приёму команды  //PD1
const int OE = 2;    //Управление шины данных РВ7..РВ0 0-выход, 1-вход           //PD2
const int WR = 3;    //Сигнал записи активный 0                                  //PD3
const int BS1 = 4;   //Выбор байта 0-младший, 1-старший                          //PD4
const int XA0 = 5;   //00-загрузка адреса, 01-загрузка данных                    //PD5
const int XA1 = 6;   //10-загрузка команды, 11-режим ожидания                    //PD6
const int PAGEL = 7; //Сигнал загрузки страницы памяти                           //PD7
const int BS2 = 8;   //Выбор байта 0-младший, 1-старший                          //PC2
const int PBD0 = 9;  //                                                          //PC0
const int PBD1 = 10; //                                                          //PC1
const int PBD2 = 11; //                                                          //PB0
const int PBD3 = 12; //Двунаправленная 8-ми разрядная                            //PB1
const int PBD4 = 13; //            шина данных                                   //PB2
const int PBD5 = 14; //                                                          //PB3
const int PBD6 = 15; //                                                          //PB4
const int PBD7 = 16; //                                                          //PB5
const int Vpp = 17;  //12v перевод в режим параллельного прогр.                   //RESET
const int RESET = 18;//Программный ресет  (подключен через диод)                 //RESET
const int XTAL1 = 19;//Вход тактового генератора                                   //XLAT1
const int Un = 20;   //Включение питания                                          //+5v
//GND
//Фюзы   (заводские настройки) //фюзы описывать не буду  
//                             //номера битов
boolean Lock1 = true;          //
boolean Lock2 = true;          //
boolean BootLock01 = true;     //
boolean BootLock02 = true;     //
boolean BootLock11 = true;     //
boolean BootLock12 = true;     //
boolean BOOTRST = true;        //H0
boolean BOOTSZ0 = true;        //H1
boolean BOOTSZ1 = false;       //H2
boolean EESAVE = true;         //H3
boolean CKOPT = true;          //H4
boolean SPIEN = false;         //H5
boolean WDTON = true;          //H6
boolean RSTDISBL = true;       //H7
boolean CKSEL0 = false;        //M0
boolean CKSEL1 = false;        //M1
boolean CKSEL2 = true;         //M2
boolean CKSEL3 = false;        //M3
boolean SUT0 = false;          //M4
boolean SUT1 = true;           //M5
boolean BODEN = true;          //M6
boolean BODLEVEL = true;       //M7
const int FuseL=228, FuseH = 219, FuseS =0; //Слова конфигурации младших, старших и защиты
      int fusel, fuseh, fuses;           //для чтения и изменений фюзов

//*******************************************************************************
void setup() {                
  //ноги на выход
  SetupPin();
  Serial.begin(9600);
  while (!Serial) {
    ; // void setup капирнул из примера
  }
}

//******************************************************************************
void loop() {
  int inByte;
  if (Serial.available() > 0) {
    // чтение из порта тоже скопировал из примера
    inByte = Serial.read();}
 //Сильно не заморачиваясь делаю контроль над программатором
 switch(inByte){
   case 1: //переводим камень в режим программирования
         {if(inizial()) PortPrint(inByte);
           else Eror(1);}
   case 2: //Чмтаем состояние
         {if(reads()) PortPrint(2);
           else Eror(2);}
   case 3: //Стираем
         {if(erase()) PortPrint(3);
           else Eror(3);}
   case 4: // и отключаем защиту
         {if(securiti()) PortPrint(4);
           else Eror(4);}
   case 5: //Восстанавливаем фюзы
         {if(writef()) PortPrint(5);
           else Eror(5);}
 }//При необходимости можно добавить ещё действий
}
//******************************************************************************
boolean inizial()
{
// Перевод микроконтроллера в режим параллельного программирования:
//Обычный алгоритм такого перевода для микроконтроллера ATmega8 заключается в следующем:
//— подать напряжение 4,5...5,5 В на вывод +5V программируемого микроконтроллера и   
//выдержать паузу не менее 100 мкс;
digitalWrite(Un, HIGH);
delay(100);
//-   при   низком   уровне   на линии RESET подать не менее шести импульсов высокого уровня на линию XTAL1;
digitalWrite(RESET, LOW);
Pulse(6,XTAL1);
//— установить на линиях PAGEL, XA1, ХАО, BS1 состояние 0000 и выдержать паузу не менее 100 не;
digitalWrite(PAGEL, LOW);
digitalWrite(XA1, LOW);
digitalWrite(XA0, LOW);
digitalWrite(BS1, LOW); 
delay(100);
//— подать на линию RESET напряжение + 11,5...12,5 В. Микроконтроллер готов к параллельному программированию.
digitalWrite(Vpp, HIGH);
if(analogRead(RdyBsy)) return true; 
SetupPin();
//      Однако этот алгоритм неприменим, если у микроконтроллера запрограммирован разряд RSTDISBL или задан 
//   режим работы его тактового генератора 
//   с кварцевым резонатором либо с внешней RC-цепью. В этом случае используют другой алгоритм:
//— установить на линиях PAGEL, XA1, ХАО, BS1 состояние 0000;
digitalWrite(PAGEL, LOW);
digitalWrite(XA1, LOW);
digitalWrite(XA0, LOW);
digitalWrite(BS1, LOW); 
//— одновременно подать напряжение +4,5...5,5 В на линию +5Уи+11,5.. .12,5В на линию RESET;
digitalWrite(Vpp, HIGH);
digitalWrite(Un, HIGH);
//— выдержать паузу не менее 100 не;
delay(100);
//— если в микроконтроллере была включена защита памяти от считывания, отключить ее (одновременно стирается все 
//содержимое памяти);
erase();
//— восстановить состояние разряда RSTDISBL в старшем байте конфигурации и при необходимости разрядов

//CKSELO—CKSEL3 в младшем байте конфигурации;
//— выйти из режима программирования, установив низкий уровень на линии RESET.
digitalWrite(RESET, LOW);
//Техническое описание микроконтроллера рекомендует для дальнейшей работы войти в режим параллельного 
//программирования заново, используя первый из описанных алгоритмов.
if(analogRead(RdyBsy)) return true; 
else return false;
}

//*********************************************************************************************************
boolean reads()
{
//— Считывание конфигурации микроконтроллера ATmega8:
//— установить на линиях ХА1 и ХАО состояние 10, разрешающее загрузку команды;
digitalWrite(XA1, HIGH);
digitalWrite(XA0, LOW);
//— установить на линии BS1 низкий уровень;
digitalWrite(BS1, LOW);
//— установить линии D7—DO в состояние 01000000 (40Н);
SaveInt(64);
//— подать на линию XTAL1 импульс высокого уровня;
Pulse(1,XTAL1);
//— установить на линиях ОЕ, BS2, BS1 низкие уровни;
digitalWrite(OE, LOW);
digitalWrite(BS1, LOW);
digitalWrite(BS2, LOW);
//— прочитать на линиях D7—DO младший байт конфигурации;
fusel = LoadInt();
//— установить на линии ОЕ низкий, а на линиях BS2, BS1 высокие уровни;
digitalWrite(OE, LOW);
digitalWrite(BS1, HIGH);
digitalWrite(BS2, HIGH);
//— прочитать на линиях D7—DO старший байт конфигурации;
fuseh = LoadInt();
//— установить на линиях ОЕ, BS2 низкие, а на линии BS1 высокий уровни;
digitalWrite(OE, LOW);
digitalWrite(BS1, HIGH);
digitalWrite(BS2, LOW);
//— прочитать на линиях D7—DO байт защиты памяти;
fuses = LoadInt();
//— установить на линии ОЕ высокий уровень.
digitalWrite(OE, HIGH);
  return true;
}

//*********************************************************************************************************
boolean erase()
{
//      Стирание памяти и отключение ее защиты:
//— установить на линиях ХА1 и ХАО состояние 10, разрешающее загрузку команды;
digitalWrite(XA1, HIGH);
digitalWrite(XA0, LOW);
//- установить низкий уровень на линии BS1;
digitalWrite(BS1, LOW);
//— установить линии D7—DO в состояние 10000000 (80Н), соответствующее команде стирания (Chip Erase);
SaveInt(128);
//— подать на линию XTAL1 импульс высокого уровня для загрузки команды в микроконтроллер;
Pulse(1,XTAL1);
//— подать на линию WR импульс низкого уровня для выполнения стирания, при этом высокий уровень на 
//линии RDY/BSYсменится низким;
Pulse(1,WR);
if(RdyBsy == HIGH)return false;
//— дождаться восстановления высокого уровня на линии RDY/BSY
while(digitalRead(RdyBsy)){};
  return true;
}

//*********************************************************************************************************
boolean securiti()
{
  return true;
}

//*********************************************************************************************************
boolean writef()
{
//Запись младшего байта конфигурации:
//— установить линии ХА1 и ХАО в состояние 10, разрешающее загрузку команды;
digitalWrite(XA1, HIGH);
digitalWrite(XA0, LOW);
//— установить на линии BS1 низкий уровень;
digitalWrite(BS1, LOW);
//— установить линии D7—DO в состояние 01000000 (40Н), соответствующее   команде   записи   конфигурации 
//(Write Fuse Bits);
SaveInt(64);
//— подать на линию XTAL1 импульс высокого уровня;
Pulse(1,XTAL1);
//— установить линии ХА1 и ХАО в состояние 01, соответствующее загрузке данных;
digitalWrite(XA1, LOW);
digitalWrite(XA0, HIGH);
//— установить линии D7—DO в состояние 11100001 (ОЕ1Н, значение младшего байта конфигурации, устанавливаемое 
//при изготовлении микроконтроллера);
SaveInt(225);
//— подать на линию XTAL1 импульс высокого уровня для загрузки данных;
Pulse(1,XTAL1);
//— установить линии BS2 и BS1 в состояние 00, соответствующее выбору младшего байта конфигурации;
digitalWrite(BS1, LOW);
digitalWrite(BS2, LOW);
//— подать на линию WR импульс низкого уровня и ждать появления высокого уровня на линии RDY/BSY
Pulse(1,WR);
while(digitalRead(RdyBsy)){};
//Запись старшего байта конфигурации:
//— установить линии ХА1   и ХАО в состояние 10, разрешающее загрузку команды;
digitalWrite(XA1, HIGH);
digitalWrite(XA0, LOW);
//— установить на линии BS1 низкий уровень;
digitalWrite(BS1, LOW);
//— установить линии D7—DO в состояние 01000000 (40Н);
SaveInt(64);
//— подать на линию XTAL1 импульс высокого уровня;
Pulse(1,XTAL1);
//— установить линии ХА1 и ХАО в состояние 01, соответствующее загрузке данных;
digitalWrite(XA1, LOW);
digitalWrite(XA0, HIGH);
//— установить линии D7—DO в состояние   11011001   (OD9H,   значение старшего байта конфигурации, 
//задаваемое при изготовлении микроконтроллера; важно установить 1 в разряде D7 (RSTDISBL), а в разряде 
//D5 (SPIEN) — О, разрешающий последовательное программирование;
SaveInt(217);
//— подать на линию XTAL1 импульс высокого уровня;
Pulse(1,XTAL1);
//— установить на линиях BS2 и BS1 состояние 01, соответствующее выбору старшего байта конфигурации;
digitalWrite(BS1, LOW);
digitalWrite(BS2, HIGH);
//— подать на линию WR импульс низкого уровня и ждать появления высокого уровня на линии RDY/BSY;
Pulse(1,WR);
while(digitalRead(RdyBsy)){};
//— установить на линии BS1 низкий уровень.
digitalWrite(BS1, LOW);
  return true;
}

//*********************************************************************************************************
void PortPrint(int a)
{
  switch(a){
    case 1:{ Serial.println ("Inicialise OK."); }
    case 2:{ Serial.println ("Fuse read OK."); }
    case 3:{ Serial.println ("erase OK."); }
    case 4:{ Serial.println ("Inicialise OK."); }
    case 5:{ Serial.println ("Inicialise OK."); }
  //return true;
  }
}

//*********************************************************************************************************
void Eror(int a)
{
  //return true;
}

//*********************************************************************************************************
boolean Pulse(int a, int led)
{
  for(int i; i<a; i++){
  digitalWrite(led, HIGH);
  delay(5);
  digitalWrite(led, LOW);
  delay(5);}
}

//*********************************************************************************************************
void SetupPin ( void)
{
  pinMode(OE, OUTPUT);    digitalWrite(OE, LOW); 
  pinMode(WR, OUTPUT);    digitalWrite(WR, LOW);
  pinMode(BS1, OUTPUT);   digitalWrite(BS1, LOW); 
  pinMode(BS2, OUTPUT);   digitalWrite(BS2, LOW);
  pinMode(XA0, OUTPUT);   digitalWrite(XA0, LOW);
  pinMode(XA1, OUTPUT);   digitalWrite(XA1, LOW);
  pinMode(PAGEL, OUTPUT); digitalWrite(PAGEL, LOW);
  pinMode(PBD0, OUTPUT);  digitalWrite(PB0, LOW); 
  pinMode(PBD1, OUTPUT);  digitalWrite(PB1, LOW); 
  pinMode(PBD2, OUTPUT);  digitalWrite(PB2, LOW); 
  pinMode(PBD3, OUTPUT);  digitalWrite(PB3, LOW); 
  pinMode(PBD4, OUTPUT);  digitalWrite(PB4, LOW); 
  pinMode(PBD5, OUTPUT);  digitalWrite(PB5, LOW); 
  pinMode(PBD6, OUTPUT);  digitalWrite(PB6, LOW); 
  pinMode(PBD7, OUTPUT);  digitalWrite(PB7, LOW); 
  pinMode(Vpp, OUTPUT);   digitalWrite(Vpp, LOW); 
  pinMode(XTAL1, OUTPUT); digitalWrite(XTAL1, LOW); 
}

//*********************************************************************************************************
int LoadInt(void)
{
int Fuse =digitalRead(PBD0)<<0|
          digitalRead(PBD1)<<1|
          digitalRead(PBD2)<<2|
          digitalRead(PBD3)<<3|
          digitalRead(PBD4)<<4|
          digitalRead(PBD5)<<5|
          digitalRead(PBD6)<<6|
          digitalRead(PBD7)<<7; 
 return Fuse;
}

//*********************************************************************************************************
void SaveInt(int Data)
{
           digitalWrite(PBD0, Data<<0);
           digitalWrite(PBD0, Data<<1);
           digitalWrite(PBD0, Data<<2);
           digitalWrite(PBD0, Data<<3);
           digitalWrite(PBD0, Data<<4);
           digitalWrite(PBD0, Data<<5);
           digitalWrite(PBD0, Data<<6);
           digitalWrite(PBD0, Data<<7);
}

 

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

та если  SPI_enabl не убил, то спокойно востанавливается все с помощью генератора от 300-500кГц. Делается на ЛН-ке.

А вообще взял за правило, с чистого кристала считать фьюзы и менять только те, что нужны.

Dmti
Dmti аватар
Offline
Зарегистрирован: 13.10.2013

Не все такие, у меня пара валяется давно, ещё атмега8. Пробовал частоту подавать, не реагируют. Думаю, кто давно или совсем недавно камни программирует, есть такие  что на последовательный программатор не реагируют.