Предлагаемое устройство эмулирует на микроконтроллере ATmega4809 абстрактный 4-битный микроконтроллер с адресным пространством в 256 байт, который можно программировать тремя кнопками и четырьмя переключателями.

Адресное пространство поделено на 16 страниц по 16 инструкций в каждой. Длина инструкции составляет 8 бит, из которых четыре старших — команда, а четыре младших — данные:



Чтобы войти в режим программирования, необходимо, удерживая кнопку 2, нажать кнопку сброса, отпустить её, за ней отпустить кнопку 2. В режиме программирования последовательный перебор инструкций в ОЗУ производится кнопкой 2. При переходе к следующей инструкции светодиоды на долю секунды показывают текущий адрес. Кнопкой 1 можно внести изменения в команду и адрес в составе текущей инструкции. При переходе к новому адресу кнопкой 2 инструкция по предыдущему адресу заносится в ППЗУ. Набрав программу, нужно нажать кнопку сброса, и произойдёт переход из режима программирования в режим выполнения программы.

Перечень команд:

0x0 — загрузить постоянное значение в порт doutB
0x1 — то же, в порт doutA
0x2 — пауза
0x3 — относительный безусловный переход назад
0x4 — загрузить постоянное значение в переменную A
0x5 — загрузить что-либо со значением переменной A
0x6 — загрузить значение чего-либо в переменную A
0x7 — произвести арифметические и логические операции с переменной A (и B)
0x8 — установить старший полубайт адреса для инструкции абсолютного безусловного перехода
0x9 — произвести абсолютный безусловный переход на заданный адрес
0xA, 0xB — действует как цикл for: каждый раз, когда команда выполняется, если переменная C (или D) больше нуля, происходит абсолютный безусловный переход на заданный адрес, затем значение переменной C (или D) уменьшается
0xC — пропустить следующую инструкцию если аргумент равен логической единице
0xD — вызвать функцию по заданному адресу
0xE — вернуться из вызванной функции
0xF — задать адрес для виртуального 4-битного ОЗУ, сохранённое по этому адресу значение можно прочитать инструкцией 0x6E и записать инструкцией 0x50.

Пример 1 — мигалка:

Адрес Инструкция Комментарий
0     1f         Включить все светодиоды на порту doutA
1     28         Пауза 500 мс
2     10         Выключить все светодиоды на порту doutB
3     28         Пауза 500 мс
4     34         Относительный безусловный переход на -4 ячейки

Пример 2 — двоичный счётчик:


Адрес Инструкция Комментарий
0     5B         DoutB = A
1     59         PWM1 = A
2     71         A++
3     28         Пауза 500 мс
4     34         Относительный безусловный переход на -4 ячейки

Пример 3 — мигалка с регулируемой скоростью (с подпрограммой):


Адрес Инструкция Комментарий
Основной цикл:
0     10         DoutA = 0x0
1     d5         Вызов подпрограммы myWait
2     1f         DoutA = 0xf
3     d5         Вызов подпрограммы myWait
4     34         Относительный безусловный переход на -4 ячейки
Подпрограмма myWait:
5     64         A = Din
6     52         C = A
7     25         Пауза 50 мс
8     a7         for(C > 0; C--) jmp 7
9     e0         Возврат

Схема:







Все необходимые для повторения файлы (плата, прошивка, и др.) — по ссылке на оригинал. Источником вдохновения для конструкции послужил близкий по возможностям немецкий тренажёр TPS.

Комментарии (6)


  1. HiTechSpoon
    14.05.2019 07:19

    А есть в этом какой-то практический смысл? В голову приходит только обучение школьников или студентов, но для этого ведь можно использовать реальный микроконтроллер или процессор.
    UPD: только что увидел, что статья в хабе «ненормальное программирование», но все-таки. =)


    1. remzalp
      14.05.2019 08:42
      +1

      подозреваю, в этом случае прочувствуется несколько лучше
      Всё же покрутить в голове логику, записать на бумаге, закодить необычным методом — на всех этапах дополнительные усилия, что улучшает запоминание


    1. andranick
      14.05.2019 09:50

      Микроконтроллер и процессор — более высокий уровень, уровень использования вычислительного устройства. То, что описано в статье — уровень разработчика архитектуры вычислительного устройства; на этом уровне реализуется исполнение скомпилированного машинного кода внутри вычислительного ядра (декодирование команд, выборка и подготовка операндов, исполнение команды и пр.).
      По моему мнению, предложенный в статье вариант — наиболее наглядный и простой способ почувствовать как реализуется выполнение команд внутри ядра процессора на уровне декодирования и исполнения микрокода. Ширины в 8 бит — вполне достаточно для этих целей.


      1. HiTechSpoon
        14.05.2019 11:20

        Вот как раз декодирование и исполнение внутри ядра процессора тут не увидеть. Мне кажется реализация такого же простого процессора на FPGA будет нагляднее в данном плане.


        1. FForth
          14.05.2019 12:00
          +1

          Полезнее ещё ядро простого процессора встроить в полезное для использования устройство.
          Пример: Gameduino со встроенным J1C ядром процессора. (на Github много форков данного процессора J1B ...)

          P.S. Вопросов появится больше, но и результат будет радовать.


  1. AVI-crak
    14.05.2019 18:37

    Одно время заморачивался оптимизацией списка аппаратных команд для абстрактного ядра мк. Свалил всё в одну кучу, и простые быстрые команды, и сложные составные, и условные, и всю математику с дсп на вырост. А потом сортировал до компактного командного слова.
    Оказалось что разрядность в 12 бит вообще идеально подходит. Достаточно компактно для быстрых команд, и без воды для составных.
    Но 12 бит — это-ж почти другая вселенная. Мк получится не совместимым на аппаратном уровне с существующими свободными данными.
    Как впрочем и четырёх битный процессор.