Собираем игру «Змейка» на макетной плате. Часть 2: «векторный» дисплей

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


    Большое разрешение — по клику

    Рисуем хвост


    У нас уже есть голова, которая одиноко бегает по полю 8×8, теперь надо нарисовать хвост. Это уже не одна точка, а много, и просто передать координаты (X, Y) на дешифраторы у нас не получится.

    Обычно на таких матрицах, как у нас, используется «динамическая индикация», причем построчный вариант: когда по очереди выдаётся содержимое каждой строки целиком. В наших условиях для этого придётся либо хранить где-то все 64 бита, либо каким-то сложным способом вычислять значение для каждой строки. Но есть ещё один вариант индикации, он тоже вполне динамический в том плане, что не все точки загораются одновременно. Мы можем воспользоваться чем-то похожим на «векторный дисплей» — выводить каждую точку по очереди, подавая на экран её координаты. В каждый отдельный момент времени будет гореть только один пиксель, который мы будем водить по экрану.

    Поскольку количество точек у нас может быть разным (в зависимости от длины хвоста), то и яркость получающейся картинки тоже будет меняться с течением игры и ростом самой змеи. Чтобы такого не происходило, мы зарезервируем фиксированное количество кадров (10 = 1 кадр для головы, 1 для яблока и 8 для хвоста) и будем гасить экран для ненужных точек.


    A — яблоко, H — голова, T# — клетки хвоста. Нарисовано в wavedrom

    Для отображения нам тоже понадобится автомат. Этот автомат будет иметь несколько частей: одна из них — счётчик кадров, который будет просто обходить по кругу 10 состояний. Возьмем для этих целей ИЕ18 и немного логики.



    Самое простое — вывод головы, в этом кадре мы просто включим экран и подадим на шину x/y то значение, которое нам даёт автомат хода. Для этого воспользуемся буфером АП6 (можно взять и АП5, но у него не такая удобная распиновка).
    Далее нам надо нарисовать хвост. Для этого мы запомним в нашем состоянии то, что только что нарисовали. Добавим к нему направление роста хвоста (с помощью схемы из предыдущей части) и выведем на экран. Чтобы знать, что нам надо выводить хвост мы просто сравним номер кадра с длиной хвоста с помощью 4-битного компаратора СП1 (U13). Хранить предыдущие координаты будем в 8-битном регистре ИР37 (или ИР27, просто они закончились...), а для получения новых воспользуемся EEPROM, таблицу для которой мы уже сгенерировали в первой части. Направление нужной секции хвоста заберём из автомата игры с помощью мультиплексоров КП15, подав на адресные входы номер кадра. Причём надо не забыть, что храним мы направление головы, которое противоположно направлению роста хвоста, а значит одну из компонент нужно проинвертировать. К счастью, отдельный инвертор ставить не придётся, ведь у КП15 есть инверсный выход. Итого:


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

    Яблоко


    Это самая «грязная» часть нашей схемы. Во-первых, потому что тут требуется случайное положение яблока, а наши автоматы не имеют ни капли случайности. Во-вторых, нам понадобиться прокинуть сигнал поедания яблока из одного автомата в другой, при этом автоматы имеют разный тактовый сигнал. По-умному это называется clock domain crossing, но мы сделаем простой костыль.

    Где взять рандом? Можно придумать псевдо-рандомный генератор, но на это понадобится нетривиальное количество логики. Другой вариант — взять тактовый генератор с другой частотой, желательно не очень стабильный, но наши NE555 и так стабильностью не отличаются. В схему мультивибратора можно добавить каких-нибудь шумных или нелинейных элементов по вашему вкусу (я добавил последовательно с резистором JFET с болтающимся в воздухе затвором). Получать рандомную координату и запоминать её мы будем в 6-битном счётчике. Готовых чипов на 6 бит нет, поэтому соединим два корпуса ИЕ10:



    В этом же узле мы поставим буфер для вывода яблока на экран по разрешающему сигналу. А также компаратор для того чтобы понять, что то, что у нас сейчас выводится на экран, совпадает с яблоком (два СП1). Не будем только сравнивать яблоко с самим собой, для этого воспользуемся 4-м битом компаратора и подадим на него сигнал разрешения с одной стороны и единицу — с другой.

    И вот тут нас поджидает грязный хак: в зависимости от серии микросхемы, задержки сигнала разрешения, паразитной емкости макетки и фазы луны компаратор может включиться чуть раньше, чем выключится драйвер U23. Более наглядно, что происходит:



    Из-за выбранной схемы синхронизации (про неё далее) такой глюк будет нам мешать. Правильно было бы его подавить с помощью задержки, например из нескольких инверторов, или вообще разнести включение и сравнение на разные фазы. Но я уже достаточно устал и просто задавил его конденсатором C5, раз уж это грязная часть схемы :)

    Тактирование и выбор нового яблока


    Основной генератор U7 тактирует кадры, их у нас 10, дальше эту частоту мы поделим на 16 с помощью ещё одного счётчика ИЕ10 (U19) и воспользуемся для тактирования шагов. Сигнал о совпадении головы с яблоком появляется только на одном кадре из 10 и не продержится до фронта импульса, переключающего кадр. Вот здесь нам нужна схема синхронизации. Я решил взять самый простой вариант: мы заведём сигнал в асинхронный вход триггера, а сбрасывать его будем на каждый новый шаг принимающего автомата.



    На выходе триггера мы получим сигнал для добавления ещё одной клетки хвоста (U6), а также для запуска счётчика, хранящего координаты головы (U21, U22), это сгенерирует новое, по возможности рандомное, яблоко.

    Вся схема



    Большая схема по клику. А как это выглядит на макетке — в начале статьи

    Детали и компоненты


    макетные платы


    Макетные платы можно взять китайские с али, но тогда на проблемы с плохими контактами уйдёт гораздо больше времени, чем на сборку непосредственно схемы. Хорошие платы рекомендует Ben Eater, это платы BB830 (белые) или WBU-202 (желтые). Набор проводов тоже лучше всего взять Wisher (WJW-60B), а в качестве мягких сойдёт любой китайский набор, даже самый дешёвый.

    микросхемы


    Я старался собрать на самой популярной отечественной серии, КР1533. На западе это серия 74ALS, но там она популярностью совсем не пользовалась. В данной схеме нет никаких критических параметров по таймингам или нагрузочной способности, поэтому можно спокойно взять серию К555 (74LS) или вообще К155 (SN74). Из импортных можно взять 74HC (но тогда для совместимости уровней придётся почти все чипы брать из этой серии) или 74HCT, которая полностью совместима с ТТЛ- и КМОП-сериями.

    Найти отечественные микросхемы оказалось непростой задачей: в популярных онлайн-магазинах они никому не нужны и все остатки давно распродали. Какие-то чипы я насобирал в местных оффлайн-магазинах, другие пришлось заказывать в интернете, но многим поставщикам неинтересно возиться с мелкими заказами, так что это было то ещё развлечение…

    Итоговый BOM получился такой (через слэш указаны возможные замены):

    ──────────────────────────────────────────────────────
    логика          │ 1× к*лн1 74*04
                    │ 1× к*ла3 74*00
                    │ 1× к*ла1 74*20
    триггер         │ 1× к*тм2 74*74
    буферы          │ 2× к*ап6 74*245 / к*ап5 74*244 (другая распиновка)
    компараторы     │ 3× к*сп1 74*85
    мультиплексоры  │ 2× к*кп15 74*251 / *кп7 *151
    счетчики        │ 1× *ие18 *163
                    │ 4× *ие18 *163 / *ие10 *161
    регистры        │ 3× *ир27 74*377 / *ир37 74*574 (другая распиновка)
                    │ 1× *ир37 74*574 / *ир27 74*377 (другая распиновка)
    EEPROM          │ 3× AT28C16 / CAT28C16
    дешифраторы     │ 1× *ид7 74*138 / ид4 74*155 (другая схема)
                    │ 1× К561ИД1 CD4028 (другая схема) / записанный AT28C16
    генератор       | 2× КР1006ВИ1 NE555
    ──────────────────────────────────────────────────────
    

    Итог


    Надеюсь, эта схема вам понравилась и, возможно, у кого-нибудь поднимется рука её повторить, или сделать что-то ещё более интересное ))

    Видео можно посмотреть на ютубе:

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

    Архив со схемой и дампами EEPROM можно скачать здесь.



    Использованные материалы


    1. Книга Харрис&Харрис, которую не устаёт рекомендовать YuriPanchul — для общего руководства.

    2. Справочник Бирюкова С.А — для поиска распиновки конкретных микросхем.

    обе книги можно найти в PDF, но бумажный вариант приятнее

    3. Сайт Ben Eater’a и его ютуб-канал — для вдохновения ))

    4. Wavedrom — для рисования диаграмм

    Всем, кто дочитал до конца, спасибо за внимание!
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 14

      +2

      Кроме как "охренеть" слов не находится.
      Не думали развести печатку? Как вариант, даже в исходном виде без ПЗУ.
      Я бы прикупил такое в виде набора-конструктора. Благо платы сейчас у китайцев стоят сущие копейки, требований особых тут нет.

        0

        Я вот всегда интересовался, кто находится в целевой аудитории таких наборов. Что с ним делать? Учиться паять?

          +2

          Наверное, да. Лично мне просто как рукоделие, потому что после работы сидеть и проектировать печатку или схему сильно впадлу и грузит мозг, а чисто позаниматься механической паяльной работой — самое то, чтобы отдохнуть. До кучи по итогам имеешь условную моргачку светодиодами с предысторией, которую можно на стенку в рамочку повесить.

            +1
            Отвечу сразу на всё:
            > Не думали развести печатку
            не думал, потому что это всё-таки не совсем завершённая конструкция, некоторые фишки хочется сделать, но на плате что-то измменить будет уже тяжело

            > кто находится в целевой аудитории таких наборов
            Да в принципе кто угодно, кому охота немного попаять. Это как «эффект икеи»: одно дело купить готовое изделие, а другое приложить к нему хотя-бы сколько-то своих сил. Даже если не разработать с нуля, то собрать. Раньше я тоже думал «да кому это нодо», но недавно попробовал собрать готовый набор (простой китайский line-follower), тоже вполне себе развлечение.
        +1
        Презабавно. Повезло Вашему сыну с отцом — такой способ отвлечения от игры на телефоне самый действенный и полезный.
        Жаль, не взлетели векторные дисплеи на современных компьютерах — сейчас пригодились бы, скажем, для удалённой отрисовки 3D графики. А ведь даже в драйверах дисплея для Windows есть соответствующий блок параметров, к сожалению, не используемый.
          +1

          Прикольно.
          Я всё же за 555 серию — считаю её более популярной, в местных магазинах (ижевских, radio18.RU, elirit.RU) её в разы больше и она в разы дешевле, интеграловскую 1533 лучше хранить для случаев, когда она реально нужна.
          Программатор предлагаю github.com/dvarkin-ru/eprom_programmer, скоро сам доделаю для nMOS 2716 (РФ5).
          Кстати, в элирите недорого собственно 2716, в радио18 — 27c128.

            0
            Да, можно собирать и на 555, и даже на 155, но в этом случае придётся проверять что нигде не превышена нагрузочная способность и вообще быть более аккуратным. 1533-я серия прощает намного больше ошибок.

            В качестве развлечения закупился 1594-й серией, но она для макеток практически непригодна: нужно брать питание с одной рельсы, а не с двух сторон, ставить конденсаторы. А если воткнуть например ЛН1 и не заземлить неиспользуемые инверторы, то получится неплохая широкополосная глушилка радиодиапазона ))
            0
            Соглашусь с комментарием выше — как насчет развести печатку и продавать в виде конструктора? Или просто продавать платы :)
              0
              К сожалению, энтузиазм уже заглох, его еле хватило на написание статьи на хабр… Фотки и видео были сняты ещё в начале марта, а потом конструкция была разобрана (зачем, может напишу чуть позже)

              Но если у кого-то есть желание сделать плату, то я буду не против ))
              +1
              Потрясающая работа цифровой схемотехнике, большое спасибо за статью.
              Не поскажите, что бы несложного почитать по проектированию конечных автоматов?
              Хочу изучить, как их правильно описывать, как реализовывать базовые вещи вроде ожидания состояния, условного перехода, счётчика.
              Нашёл, что есть приложение jflap для их моделирования, но у меня есть сомнения, что без толкового руководства что-то получится.

              Что касается кр1533, то посмотрите на Анионе. Если не считать дорогие золотоногие, то насчитал 100 уникальных наименований этой серии при средней цене 13.6 руб за корпус.
                0
                Глобально по теории автоматов не подскажу, тема достаточно широкая. Но если вам достаточно автоматов Мура, то там всё просто. В качествет мануала с примерами и задачами хорошо подойдёт книжка Харрисов.

                За анион спасибо, к сожалению в своё время не нашёл его поиском. С доставкой я заказывал в gkel.ru и elecom22.ru, настаивать не буду, всегда сравнивайте цены сами ;)
                +1
                Ого! У меня состояние того кота, который узнал, что мир не ограничивается его квартирой.
                Как челюсть отвисла, так и хожу. :)
                Колоссальный труд и фундаментальные знания!
                  0
                  Панелька многоцветная? «Яблоко» бы зелёным сделать.
                  Но сама работа потрясает.
                    0
                    Была идея сделать красно-зелёную, но RGB-панельку потеряла почта. Мысль была такая: сделать отдельный ИД7 на красный канал и ещё один ИД7 на зелёный. Первый включать только для яблока, второй — для остального, но не случилось…

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое