Легкая прошивка микроконтроллеров Atmel AT89 с помощью Arduino Uno — пошаговое руководство
Компоненты и материалы
- Arduino UNO — 1 шт.
- Микроконтроллер AT89C52 — 1 шт.
- Керамический резонатор 12 МГц — 1 шт.
- Конденсаторы: 2×33 пФ, 10 мкФ, 510 пФ (ошибка в оригинале: 510 ом — резистор) — по 1 шт.
- Резистор 8,2 кОм — 1 шт.
- Светодиод (любого цвета) — 1 шт.
- Перемыечные провода «папа-папа», «папа-мама» — набор
- Паяльник и припой
Необходимые инструменты
- Паяльник
Программное обеспечение
- Arduino IDE
- Программатор 8051 SPI Programmer (запускается на ПК, общается с Arduino по Serial)
О проекте
В этом руководстве показано, как превратить Arduino Uno в SPI-программатор для микроконтроллеров серии AT89 (в частности AT89C52). Прошивка осуществляется через последовательный порт: на Arduino загружается скетч-программатор, а на компьютере запускается утилита 8051 SPI Programmer, которая отправляет HEX-файл.
Шаг 1: Подключение микроконтроллера
Соедините выводы AT89C52 с Arduino согласно таблице:
| AT89C52 | Arduino Uno |
|---|---|
| Pin 6 (P1.5 / MOSI) | Pin 5 (D5) |
| Pin 7 (P1.6 / MISO) | Pin 4 (D4) |
| Pin 8 (P1.7 / SCK) | Pin 3 (D3) |
| Pin 9 (RST) | Pin 2 (D2) |
Шаг 2: Генератор тактовой частоты
Подключите кварц 12 МГц к выводам 18 (XTAL2) и 19 (XTAL1). От каждого вывода к земле (Pin 20) поставьте по конденсатору 33 пФ.
Шаг 3: Питание
Вывод 40 (VCC) — на 5V Arduino, вывод 20 (GND) — на GND Arduino.
Шаг 4: Индикация (светодиод)
Подключите светодиод через токоограничивающий резистор (≈510 Ом) к любому свободному порту AT89C52 (например, P1.0) для проверки работы прошитой программы.
Шаг 5: Программная часть
- Загрузите в Arduino скетч
SPI_Programmer.ino(приведён ниже). - Скачайте и запустите 8051 SPI Programmer на ПК.
- Выберите COM-порт Arduino, укажите HEX-файл и нажмите «Program».
Код для Arduino (SPI-программатор)
#define dummyData 0xAA
#define RDY 75
#define NRDY 76
const int _MISO = 4;
const int _MOSI = 5;
const int _CLK = 3;
const int RST = 2;
byte data;
byte AL, AH; // 16-битный адрес
byte lockByte;
byte SigH, SigL;
void setup() {
pinMode(_MISO, INPUT);
pinMode(_MOSI, OUTPUT);
pinMode(_CLK, OUTPUT);
pinMode(RST, OUTPUT);
Serial.begin(115200);
}
void loop() {
while (!Serial.available());
if (Serial.available() > 0) switch (Serial.read()) {
case 'p': Serial.write(progEnable()); break;
case 'r': readProgmem(); Serial.write(data); break;
case 'a': while(!Serial.available()); AL = Serial.read(); break;
case 'A': while(!Serial.available()); AH = Serial.read(); break;
case 'd': while(!Serial.available()); data = Serial.read(); break;
case 'S': AH = 0; AL = 0; SigH = readSign(); Serial.write(SigH); break;
case 's': AH = 2; AL = 0; SigL = readSign(); Serial.write(SigL); AH = 1; AL = 0; SigL = readSign(); Serial.write(SigL); break;
case 'o': digitalWrite(RST,1); break;
case 'c': digitalWrite(RST,0); break;
case 'e': eraseChip(); Serial.write(RDY); break;
case 'j': break;
case 'w': writeProgmem(); break;
}
}
unsigned char SendSPI(unsigned char data) {
uint8_t retval = 0;
uint8_t intData = data;
for (int ctr = 0; ctr < 7; ctr++) {
digitalWrite(_MOSI, (intData & 0x80) ? HIGH : LOW);
digitalWrite(_CLK, HIGH);
delayMicroseconds(1);
int t = digitalRead(_MISO);
digitalWrite(_CLK, LOW);
retval = (retval << 1) | (t ? 1 : 0);
intData <<= 1;
delayMicroseconds(1);
}
digitalWrite(_MOSI, (intData & 0x80) ? HIGH : LOW);
digitalWrite(_CLK, HIGH);
delayMicroseconds(1);
int t = digitalRead(_MISO);
digitalWrite(_CLK, LOW);
retval = (retval << 1) | (t ? 1 : 0);
return retval;
}
byte progEnable() {
SendSPI(0xAC); SendSPI(0x53); SendSPI(dummyData); return SendSPI(dummyData);
}
void eraseChip() {
SendSPI(0xAC); SendSPI(0x9F); SendSPI(dummyData); SendSPI(dummyData); delay(520);
}
void readProgmem() {
SendSPI(0x20); SendSPI(AH); SendSPI(AL); data = SendSPI(dummyData);
}
void writeProgmem() {
SendSPI(0x40); SendSPI(AH); SendSPI(AL); SendSPI(data);
}
void writeLockBits() {
SendSPI(0xAC); SendSPI(lockByte); SendSPI(dummyData); SendSPI(dummyData);
}
void readLockBits() {
SendSPI(0x24); SendSPI(dummyData); SendSPI(dummyData); lockByte = SendSPI(dummyData);
}
byte readSign() {
SendSPI(0x28); SendSPI(AH); SendSPI(AL); return SendSPI(dummyData);
}
Схемы подключения
Полные схемы собраны в разделе «Schematics» оригинального проекта. Основные моменты: кварц с конденсаторами, питание, SPI-линии и Reset. Рекомендуется собрать схему на макетной плате или спаять на щите для надежности.
Производственный процесс
- Легкая прошивка микроконтроллеров Atmel AT89 с помощью Arduino Uno — пошаговое руководство
- Декодирование PPM-сигнала RC-приёмника на Arduino: пошаговое руководство
- Arduino UNO + WiFi Shield: реальный график температуры в вебе через Serial
- ThimbleKrox: управление мышью с пальца на Arduino Micro и MPU-6050
- Система управления светом на Intel Curie (Arduino 101) с детекцией движений
- Беспроводная прошивка Arduino через Bluetooth HC-05: щит без USB-кабеля
- Arduino датчик двери: мгновенные уведомления в Facebook Messenger через IFTTT
- Веб-управляемый XY-плоттер на Arduino с контроллером шаговых двигателей
- Калькулятор на Arduino с 16x2 LCD и клавиатурой 4x4
- Управление 4-пиновым PWM-вентилятором 25 кГц на Arduino Uno — Сборка, код и тесты