Тема для обсуждения Параллельный прогромматор
- Войдите на сайт для отправки комментариев
Сб, 26/10/2013 - 17:01
Попался сайт с описанием параллельного прогромматора. Скопировал текст с сайта (он в виде каментария) и наскорую руку набросал основу, не доконца. Собирать даже не пытался. Выслушаю любые мнения.
/*Содрал с сайта 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); }
та если SPI_enabl не убил, то спокойно востанавливается все с помощью генератора от 300-500кГц. Делается на ЛН-ке.
А вообще взял за правило, с чистого кристала считать фьюзы и менять только те, что нужны.
Не все такие, у меня пара валяется давно, ещё атмега8. Пробовал частоту подавать, не реагируют. Думаю, кто давно или совсем недавно камни программирует, есть такие что на последовательный программатор не реагируют.