Мы принимаем как должное удобства современных микроконтроллеров - все ключевые компоненты интегрированы в один корпус: флэш-память/EEPROM, SRAM, само процессорное ядро, PLL, ADC/DAC, PWM, последовательные порты и многое другое.
Но так было не всегда. Первым монолитным микроконтроллером был Intel 8048 (MCS-48) выпущенный в 1976 по n-МОП технологии. Не планировалось что у него будет длинный жизненный цикл и уже через 4 года в 1980 на смену ему пришел Intel 8051 (MCS-51), завоевавший мир. Он имел на борту 4КиБ однократно-программируемой памяти, 128 байт SRAM, GPIO, последовательные порт и, собственно, 8-битное процессорное ядро. Intel 87C51FC был вариантом на базе УФ-стираемой EPROM памяти (объемом 32КиБ), C-версия - на КМОП процессе, объем памяти увеличен до 256 байт. Ядро 8051 не было особенно производительным - т. к. даже самые простые операции требовали 12 тактов, так что при тактовой частоте 20МГц он едва мог сделать миллион операций в секунду. Также отсутствовала команды деления 16-и битных чисел (было только 8/8->8), впрочем, для того времени это было повсеместно. Конечно, современные 8051-совместимые ядра зачастую на порядки быстрее (и по тактовой частоте, и по количеству тактов на команду).
Пару недель назад ко мне в руки случайно попал D87C51FC-20 - и я решил его запустить, чтобы прочувствовать проверенные временем технологии. Сразу отмечу - не стоит тут искать практической пользы, это скорее экскурс в историю на 44 года назад...
Мне всегда было интересно, что там внутри и какая толщина кварцевого окна, так что я пожертвовал AMD AM27C64. Окно оказалось толщиной примерно 1мм и приклеено на удивление хорошо:
Мы привыкли думать, что плоские оптические окна не влияют на изображение и через них все можно рассмотреть без ограничений. Но это верно только для объектов на условной бесконечности, а вблизи, когда мы наблюдаем с большой числовой апертурой (что обычно делают для повышения разрешения в случае микроскопа) - плоское окно вносит сферическую аберрацию и для объективов с апертурой примерно более 0.3 - разрешение начинает ухудшаться, а не увеличиваться. Аналогичная проблема есть и при попытке увидеть данные на компакт-диске - со стандартным объективом с апертурой 0.3 видно лучше, чем с 0.7.
Тут самое время достать козырь - объектив с коррекцией толщины стекла (изначально их делали для контроля ЖК мониторов на производстве). На фотографии ниже - слева 87C51 без коррекции толщины стекла (низкий контраст и разрешение из-за сферической аберрации), справа - с коррекцией на 1.05mm стекла:
Теперь можно сфотографировать весь кристалл через кварцевое окно:
Стираем старые данные
Чип стирается относительно высокой дозой УФ излучения. Обычно используются кварцевые лампы излучающие 254нм. Я попробовал стереть светодиодом на 245nm - но у него была настолько маленькая оптическая мощность / крошечный КПД, что даже через час ни одного бита не стерлось. Видимо для длин волн короче 350нм ртутные лампы пока безусловно разрывают полупроводниковые светодиоды.
Некоторое время назад для другого проекта я купил странные ртутные лампы требующие 10v/300mA. Их продают в версии "с озоном" (кварцевая колба, пропускает линию ртути 185нм) и "без озона" (излучение 254нм и далее). Для стирания данных, конечно, лучше использовать 254нм, но у меня была более злая версия. Интересно, что только верхняя часть спирали лампы покрыта оксидным слоем для увеличения эмиссии электронов.
Лампа работает очень необычным образом. Включать её нужно блоком питания с напряжением ~14-15В и ограничением тока 300mA. При включении спираль нагревается до красна, и испаряет ртуть из пластины с амальгамой.
Когда давление паров достаточно повышается - зажигается разряд между верхними частями спирали, и резистивный нагрев спирали автоматически резко снижается. Эта фотография сделана в защитных очках, камера с УФ фильтром. Все тело должно быть закрыто, т. к. и 185 и 254нм вызывают рак кожи и катаракту. Озон ядовит. В общем, это лучше не повторять, и стирать лампой без озона.
Когда кварц так светится голубым - нужно бежать!
Лампа установлена в банке с огурцами (без огурцов), с алюминиевой фольгой с внутренней стороны. Обычное стекло банки не пропускает излучение короче 365нм. Точка излучения лампы была примерно в 2 сантиметрах от окна микросхемы, и содержимое стиралось примерно за 10 минут.
Прошивка
С народным программатором MiniPro TL866 - никаких сложностей (сейчас на него есть open-source софт).
Пишем демо-программу
Что ж, завязываем с фотографиями - пора писать код! В дополнение к стандартному мигающему светодиоду я решил также найти простые числа и напечатать их через последовательный порт (чтобы задача была не слишком сложная, и не слишком тривиальная вычислительно). Изначально я попробовал пойти по пути Jay Carlson и попробовал использовать современную IDE 8051-совместимых чипов от Silicon Labs (Simplicity Studio). К сожалению, там бинарная совместимость похоже только для GPIO, но не для последовательного порта (что не удивительно, последовательный порт в оригинальном 8051 очень уж простой). Так что я перешел на open source SDCC с которым все пошло как по маслу.
Я не хотел усложнять код кольцевыми буферами и прерываниями, и отправляю данные побайтно. Единственная оптимизация, которую я тут сделал - проверка завершения отправки до отправки следующего байта, а не после (как это сделано в большинстве примеров). Это позволяет частично распараллелить работу последовательного порта и вычислений. Для того, чтобы это работало и для первого байта - я устанавливаю флаг завершения передачи предыдущего байта TI = 1 в начале программы.
#include <8051.h>
#include <stdio.h>
#include <stdbool.h>
int putchar(int c) {
while (TI==0); /* Wait until transmission is complete */
TI = 0;
SBUF = c;
return c;
}
void toggle_led(void)
{
P1_0 = !P1_0;
}
int main (void)
{
int i, j, loop_limit;
bool is_prime;
//Serial port speed. Perfect 9600 for 18.432MHz crystal
TH1 = (unsigned char)(256-5);//No "overflow in implicit constant conversion"
TMOD = 0x20;
SCON = 0x50;
TR1 = 1;
TI = 1;
printf("Hello world!\r\n");
printf("Let's calculate some primes: 2");
while (1)
{
for (i = 3; i <= 32000; i+=2) {
loop_limit = 180;
//We should not calculate square root on 8051 :-)
if(i-1<loop_limit)loop_limit = i-1;
is_prime = true;
for (j = 2; j <= loop_limit; ++j) {
if (i % j == 0) {
is_prime = false;
break;
}
}
if (is_prime) {
toggle_led();
printf(" %d", i);
}
}
printf("\r\nHere we go again: 2");
}
}
Т. к. в 8751 нет PLL (что не удивительно), получить требуемую скорость работы последовательного порта может оказаться сложнее, чем кажется. Скорость последовательного порта определяется частотой кварца и предельным значением счета таймера1 (TH1). Изначально я запускал 8751 от кварца с максимальной частотой 20Мгц и TH1=256-5 - но данные последовательного порта не удавалось корректно прочитать на компьютере. А вот осциллограф декодировал корректно. Оказалось, что скорость последовательного порта получилась с ошибкой в 9% (10416 бод вместо 9600, по формуле X = F/(12*32*Y) где F это частота кварца и Y - предел счета таймера). Можно было бы сконфигурировать USB-UART адаптер CP2102 на эту частоту, или подобрать другой кварц, который дал бы меньшую ошибку.
Оказалось, что с кварцем на 18.432Mhz и таймером 256-5 - частота получается идеальная, как будто этот кварц и был создан для этой задачи. (Комментатор за кадром: Именно так)
Собираем прототип
P1.0 (pin 1): LED.
Reset (pin 9): Active high. Притягиваем к GND резистором, и к VCC через небольшой электролитический конденсатор. Это обеспечит сброс микроконтроллера при подаче питания.
TXD (pin 11): Выход последовательного порта.
XTAL1 и XTAL2 (pins 18 and 19): Кристалл на 18.432Mhz. Заработало без внешних конденсаторов, что вероятно дает некоторую незначительную ошибку частоты и меньшую стабильность. Паразитных емкостей макетной платы однозначно недостаточно (~2pF).
GND (pin 20) и VCC (pin 40): 5V питание и земля.
EA (pin 31): Для отключения внешней памяти (её у нас нет) - подключаем к VCC.
Запускаем
С корректными настройками последовательного порта - все работает!
Если посмотрим на TX осциллографом при передачи разных простых чисел, можно увидеть что-то неожиданное:
Когда печатаем трехзначное число - задержка между пробелом и первой цифрой ~1.25ms, 1.8ms для четырехзначного и 2.5ms для пятизначного. Почему так получается?
После того как printf(" %d", i) печатает пробел, микроконтроллеру нужно конвертировать число в строку и этот перевод без аппаратного деления 16-и битных целых чисел занимает достаточно большое время, так что даже на скорости 9600 бод заметно. Больше знаков - больше делений - больше задержка на конвертацию.
Резюме
Заметную часть времени до рабочего кода съели 8 итераций стереть-записать, раньше для этого были полноценные отладочные платы с кодом во внешней памяти. Самые необходимые фичи современных микроконтроллеров уже существуют 87C51 - он очень сильно обогнал своё время. Тем не менее, современные контроллеры на этой задаче ожидаемо были бы намного проще в работе:
Производительность. 1(один) 8-bit MOPS против ~50-150 32-bit MOPS в современных микроконтроллерах за 1-2$. Разрыв в математике еще больше, т.к. теперь мы избалованы относительно быстрым делением и умножением. Вместо написания уникального ручного кода деления на 10 сдвигами - можно просто делить и не переживать. Теперь и аппаратной арифметикой с плавающей точкой местами никого не удивить.
PLL. Сейчас можно поставить самый популярный/дешевый кварц на 8Mhz и сконфигурировать почти любую удобную частоту, не собирая библиотеку кварцев на все случаи жизни. Уникальные кварцы теперь нужны в основном только в ситуации где нужен низкий фазовый шум (высокоскоростные интерфейсы, ЦАП/АЦП высокого разрешения и проч.).
Аппаратный отладчик и программирование через JTAG - обеспечивает очень быстрые итерации.
Последовательные порты (и другие интерфейсы) с буферами и гораздо более высокими скоростями.
Внутренний сброс, brown-out detection, watchdog timer.
Список, конечно, можно продолжать...
Так что, несмотря на то что зачастую 8051-совместимые микроконтроллеры дешевле, разработка под них требует больше усилий и времени (=денег). Но для применений с очень большим объемом (миллионы штук), где задача относительно несложная и не требует много математики (условная микроволновка) или уже есть наработанная база готового кода - общая стоимость проекта может оказаться минимальной, потому наследники 8051 ставят в новые продукты и сегодня (и нет предпосылок к уходу 8051 на пенсию даже при наличии свободных/условно-бесплатных ядер RISC-V).
Комментарии (37)
MaFrance351
12.05.2024 14:55наследники 8051 ставят в новые продукты и сегодня
Сам привык писать под AVR/ARM, но иногда таки поглядываю на некоторые чипы 8051 типа тех мелких от Nuvoton. Уж больно вкусная цена даже с учётом большей сложности разработки.
AndreiVorobev
12.05.2024 14:55Имхо, но лучше присмотритесь к ch32v[003]. Продаются чуть ли не на развес (10-20 центов за штуку) и имеют полноценное 32 битное risc-v ядро.
MaFrance351
12.05.2024 14:55Сейчас вот как раз пилю проект на CH32V307VCT6. Забавный довольно чип, может, и в своих чисто любительских поделках применю потом...
Sun-ami
12.05.2024 14:55+2Команда деления у этого микроконтроллера была. Но в ней было мало смысла, потому что делимое было всего лишь 8-разрядным.
BarsMonster Автор
12.05.2024 14:55+1Да, именно так, подкорректировал. И даже это за 48 тактов... Но что есть то есть )
strvv
12.05.2024 14:55+2Я пока внимательно не смотрел код, просто прочитал статью, но я ограничение делал в 96 году с решетом Эрастофена по корень квадратный из уже известных корней. В 16 битном исполнении.
И корень и деление там тоже делал целочисленным извратом типа сдвига. Может в старых тетрадках, если жена до них не добралась - найдётся :)
По 8051/PDP11 UART - имхо исходная частота у них идёт от IBM, и она 11.059МГц(ИМХО).
(нашел по данной частоте первой же ссылкой - https://electronics.stackexchange.com/questions/283044/the-crystal-oscillator-used-in-uart-is-of-11-059mhz-why , а так - сам же считал - сразу же делитель на 12, особенность конвеера 8051 и потом множители)
Можно посчитать обратно от точных значений 115к, 57к, 48к, 32к, ... 9600, это число имеет эти стандартные скорости делителями. Больше пока ничего вспомнить не могу.
Это вспомнилось в том что 12МГц давало 10400 бод вместо 9600 в 8051 ядрах сименса в автомобилях.
dlinyj
12.05.2024 14:55+5Спасибо за классную статью!
Когда я разбирался с УФ ПЗУ, тоже провел ряд экспериментов, лампа для ногтей не годится для стирания. Но личный опыт показал, что проще, дешевле, а главное безопаснее купить готовый УФ стиратель для микросхем, он ещё и таймером снабжён. Все подробности в моей статье https://habr.com/ru/companies/ruvds/articles/648649/
slog2
12.05.2024 14:55+1Мои первые программы для однокристальных процессоров были для 87c51. Отладка программы это мучение. А потом наступило настоящее счастье, Atmel выпустил АТ89С51 с флэш памятью.
strvv
12.05.2024 14:55Было тогда много ядер 8051 с внешней памятью. порт А и С, если мне память не изменяет. и А - младшие адреса и шина данных.
slog2
12.05.2024 14:55+2Надо сказать что вариант с EEPROM 87С51 в то время были какие-то невероятно дорогие, и использовались в основном для отладки программ, чтобы потом рабочую программу прошить в однократно-прошиваемые 80С51.
VT100
12.05.2024 14:5580 - вообще без памяти программ на кристалле. 87 были подороже - с окошком для стирания и подешевле - без окошка.
elprog74
12.05.2024 14:55+1В гараже до сих пор лежит с десяток плат эмуляторов 8031. Подключались к компьютеру через LPT порт. Оболочка позволяла отлаживаться на ассемблере и на Паскале. Разумеется точки останова, хождение по шагам и т.д.
boojum
12.05.2024 14:55+1Китайцы любят систему команд MSC51
Вот, например, вполне актуальное семейство чипов CH55X
Аппаратный USB, АЦП, watchdog и прочее. Флешка конечно же встроена, никаких УФ окошек.
~30 руб за чип в розницу на Али с учётом доставки
~100р отладочная плата там же
Arduino в наличии :)HardWrMan
12.05.2024 14:55+1Да, у них почти во всех "народных" МК юзается MCS51. При этом, они его реализовали так, что оно выглядит как на стероидах: 1 такт на команду и десятки мегагерц в частоте. Например, внутри FTDI тоже юзается ядро MCS51.
green88
12.05.2024 14:55И не только у них. Валяется шустрый MCS51 (50 MIPS!) ds89c420 от Dallas-а фиг знамо каких годов.
Давеча ковыряюсь с 10" IPS DMI планшетом. И вот что мы в нём наблюдаем:
Separated OS CPU core runs user 8051 code or DWIN OS system, user CPU is omitted in practical application.
- Standard 8051 architecture and instruction set, 64Kbytes code space, 32Kbytes on-chip RAM.
- 64-bit integer mathematical operation unit (MDU), including 64 bit MAC and 64 bit divider.
- Built-in software WDT, three 16-bit Timers, 12 interrupt signals with the highest four interrupt nesting. 22IO, 4 UARTs,1 CAN, 7 12-bit A/Ds, 2 16-bitadjustable-resolution PWM.
- Support IAP online simulation and debugging, unlimited number of breakpoints.
- Upgrade code online through the DGUS system.
Javian
12.05.2024 14:55+1Принцип работы УФ-лампы был загадкой - как она от 12 вольт загорается и зачем спираль. Китайцы продают "устранители запаха обуви", в которых стоят две эти лампы.
lexab
12.05.2024 14:55+2Лампа зачётная! Похоже что от спектрофотометра. Внутри нее вероятно кроме ртути ещё и дейтерий. Спектр бы посмотреть Wiki
BarsMonster Автор
12.05.2024 14:55+3Слишком дешевая она для спектрофотометра, буквально пару баксов стоит... Так что думаю там особо ни на что кроме ртути денег не потратили ) Но есть повод расчехлить...
boojum
12.05.2024 14:55+3Лисин её у себя на канале обозревал было дело.
Без замеров спектра правда, но с макросъемкой как всегда )
BarsMonster Автор
12.05.2024 14:55+4Линий дейтерия на 486nm и 656nm нет, так что однозначно чистая ртуть.
MaFrance351
12.05.2024 14:55+3Это лампа от дешёвых обеззараживателей для обуви. Китайцы их часто продают сразу в комплекте с резистором и гасящим конденсатором для подключения напрямую к сети.
Javian
12.05.2024 14:55Для подключения к сети 220 вольт её продают с гасящим конденсатором.
MaFrance351
12.05.2024 14:55+4Именно так. GTL-3 она называется:
https://radiokot.ru/artfiles/6467/
Я для этих целей использую советский стиратель памяти "Фотон" (продававшийся как косметический прибор).
Javian
12.05.2024 14:55Когда я её купил из любопытства, удивленный низким напряжением и необычной конструкцией. У меня не было конденсатора как на схеме продавца, и я решил просто подать переменный ток с трансформатора, ограничив мощным переменным резистором до указанного продавцом. Было интересно наблюдать как разгорается лампа при разных токах.
Практического применения не придумал, описания принципов работы не нашел. Пока через несколько лет не прочитал в этой статье.
MaFrance351
12.05.2024 14:55+1Предположу, что принцип основан на том, что нить накала нагревается и начинает испускать электроны, что обеспечивает зажигание разряда (а активирующая обмазка на нитях это облегчает). А после зажигания потребляемый ток резко возрастает, отчего нить больше не греется.
Кстати, упомянутый мною "Фотон" тоже очень примечательный девайс - там безэлектродная УФ-лампа (просто колбочка с парами ртути) и ВЧ-генератор на сверхминиатюрной лампе.
Javian
12.05.2024 14:55Ремонтировал коллеге этот Фотон несколько лет назад - пробило подстроечный конденсатор (который выглядывает из под верхней крышечки корпуса) . Ртуть там была в виде нескольких металлических шариков.
BarsMonster Автор
12.05.2024 14:55+3Все-же там есть что-то еще... В 760нм и далее - есть отличия от спектра ртути, лишние линии. Интрига!
Suvorow
12.05.2024 14:55+1Исходно, у 8751 максимальная тактовая была 12 мегагерц, а 20 - это уже второе поколение. Поэтому "родной связной" кварц у 8751 был 11,0592 МГц. А 18,432 МГц - это "писишный" связной кварц. К 20-мегагерцевым основной связной кварц был 19,6608 МГц. Все эти кварцы популярны и сейчас. В мышах использовались пьезокерамические резонаторы на 18,432, несмотря на то, что мыши давно стали USB-шными. У меня есть 8751 в более старом металлокерамическом корпусе "с позолотой", там кварцевое окошко не вклеено в керамику, а в металлической крышке.
zatim
Я на АТ89С2051 даже делал генератор телевизионного сигнала. Правда, писать код пришлось на исключительно на ассемблере и считать каждый такт.
BarsMonster Автор
Вот, это именно оно. Дополнительный труд программиста часто стоит сотен и тысяч микроконтроллеров...