Предел минимального Hello Word на AVR составляет 2 байта

За эту неделю появилось сразу две статьи на хабре и одна в блоге, где авторы соревновались в написании минимально возможной программы мигания светодиодом для микроконтроллеров AVR.
В самой последней статье автор предложил программу длиной всего в 4 байта (!)
Ну как тут можно устоять перед брошенным вызовом?!
И в этой статье я предлагаю программу мигания светодиодом с частотой, заметной на глаз и размером всего в 2 байта.

2 байта – это минимально возможная длина программы, поскольку размер адресуемой ячейки программной памяти в микроконтроллерах AVR составляет 16 бит или 2 байта. Таким образом, программа, а точнее одна инструкция (которая может располагаться по абсолютно любому адресу) будет занимать одну ячейку программной памяти.

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

Секрет программы состоит в том, что некоторых микроконтроллерах семейств Tiny и Mega есть примечательная фича, которая позволяет всего одной командой инвертировать состояние разрядов регистров PORTА, PORTB и PORTD. Такую интересную фичу реализует команда sbi A,b

Команда sbi A,b предназначена для установки бита регистров ввода/вывода, которые имеют адреса от 0 до 31.
Эта команда в двоичном виде выглядит следующим образом:

1001 1010 AAAA Abbb

Первые восемь бит 1001 1010 являются кодом операции – это постоянная составляющая команды.
В битах ААААА записывается адрес регистра ввода/вывода в адресном пространстве ввода/вывода. Для адреса отводится 5 бит и именно поэтому, команда имеет ограничение по адресам (0..31).
В младших трех битах bbb располагается номер изменяемого бита (0..7).

Теперь вернемся к той самой примечательной фиче, которая позволяет инвертировать состояние разрядов регистров PORTB и PORTD.

Давайте заглянем в даташит на микроконтроллер ATtiny2313:

image

Такая возможность точно присутствует в микроконтроллерах ATtiny2313, ATtiny13, ATtiny24/44/84 .
В микроконтроллерах из семейства mega такая удобная функция есть в ATmega48A/PA/88A/PA/168A/PA/328/P. А вот в ATmega8A/16A/32A эта функция отсутствует.
А про остальные микроконтроллеры с уверенностью сказать не могу.
Для того что бы узнать, присутствует ли такая функция в микроконтроллере, можно поискать в даташите словосочетание Toggling the Pin.

Таким образом, прописав, к примеру, команду sbi PINB,0 можно проинвертировать состояние нулевого разряда регистра PORTB.

А что нам это даст?

А это нам дает включение/отключение подтягивающего резистора в нулевом разряде порта B (не забывайте, что после сброса все регистры ввода/вывода обнуляются, поэтому порты B и D настроены на вход). Сопротивление встроенного резистора составляет 30..50 кОм. Однако, даже такого сопротивления вполне хватит, чтобы зажечь низко потребляющие синие, красные и белые светодиоды. А вот на зеленые светодиоды тока уже будет не хватать.
Лично я такой способ запитки светодиодов использую довольно часто. Красные и синие светодиоды типоразмера 0805 и 0603 горят вполне сносно при напряжении питания 5 В.

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

image


Итак, управлять светодиодом при помощи одной команды мы научились.
Теперь, если эту команду записать в программную память микроконтроллера, например по адресу 0х0000, то микроконтроллер будет работать следующим образом:
По нулевому адресу будет встречена команда sbi PINB,0 и после ее выполнения установиться в единицу нулевой разряд PORTB, включится подтягивающий резистор и зажгет светодиод. А далее, до конца программной памяти, микроконтроллер будет встречать только 0xFFFF. Такие инструкции микроконтроллеру неизвестны, поэтому микроконтроллер просто будет пропускать их, затрачивая на каждую один такт и увеличивая на единицу программный счетчик.
После того как программный счетчик досчитает до конца памяти, он переполниться и сбросится в ноль, то есть произойдет переход на адрес 0х0000, где вновь будет выполнена команда sbi PINB,0. После выполнения команды нулевой разряд PORTB сбросится в ноль, отключится подтягивающий резистор и светодиод погаснет.

Теперь давайте посчитаем, с какой частотой будет мигать светодиод. В качестве микроконтроллера выберем, к примеру, ATtiny2313. В этом микроконтроллере программная память составляет 2048 байт. Каждая ячейка программной памяти занимает 2 байта. Адресное пространство программной памяти представлено адресами от 0 до 1023. То есть всего 1024 адреса. После подачи питания микроконтроллер начнет выполнение программы с адреса 0х0000. Когда микроконтроллер дойдет до адреса 1023, то на следующий такт произойдет обнуление программного счетчика. То есть произойдет переход на адрес 0х0000.

Все команды в нашей программе выполняются за один такт. Поэтому, светодиод будет переключаться в противоположное состояние один раз за 1024 тактов. Допустим, микроконтроллер работает на частоте 1 МГц. На этой частоте один такт составляет 1 мкс. Таким образом, переключение светодиода будет происходить каждые 1024 мкс. Как известно частота – это обратная величина периода. А период одного мигания составляет удвоенное время между переключениями светодиода 1024 мкс * 2 = 2048 мкс. Откуда получаем частоту мигания светодиода 1/(2048 мкс) = 488 Гц.

Многовато получилось. Человеческий глаз на такой частоте мигания не заметит. Чтобы частота мигания была заметна на глаз, нужно будет понизить частоту. Для этого можно затактировать микроконтроллер от тактового генератора watchdog таймера, частота которого составляет около 128 кГц. Но в реальности частота может отличаться на 3..4 кГц, так как таймер не предназначен для точных отсчетов времени.

128 кГц – это в 8 раз ниже 1 МГц. Поэтому и частота мигания будет в 8 раз ниже 488 Гц / 8 = 61 Гц. То же много. На глаз мигание заметно не будет.

Чтобы еще понизить частоту, следует включить fuse-бит CKDIV8, отвечающий за деление частоты на 8. Тогда тактовая частота составит 128 кГц/8 = 16 кГц, а частота мигания уменьшится еще в 8 раз и составит 61 Гц / 8 = 7,6 Гц. А вот такая частота уже вполне будет заметна на глаз.

Но будьте очень аккуратны при понижении частоты до таких значений!

Помните важное правило: если вы программируете микроконтроллер последовательным внутрисхемным программатором (программирование через SPI), то тактовая частота микроконтроллера должна быть, по крайней мере, в 4 раза выше, чем частота программирования.
То есть, при тактовой частоте микроконтроллера 128 кГц частота работы программатора (частота SPI) должна быть ниже

128 кГц/4 = 32 кГц.

А при тактовой частоте 16 кГц частота программирования должна быть ниже

16 кГц/4 = 4 кГц.

Прежде чем понижать тактовую частоту до 16 кГц, убедитесь, что ваш последовательный программатор способен программировать на частоте ниже 4 кГц.
А иначе вы рискуете «заблокировать» микроконтроллер!
К параллельным программаторам это ограничение не относится.


Теперь давайте, наконец, напишем нашу программу.
Писать программу будем в блокноте и сразу в машинных кодах.

Мы уже знаем, как выглядит команда sbi A,b

1001 1010 AAAA Abbb

Осталось подставить нужные биты.

Зажигать будем светодиод, который подключен к нулевому разряду порта В. В микроконтроллере ATtiny2313 адрес PINB = 0x16. В двоичном виде 0x16 = 0b10110.
Изменять будем нулевой бит, поэтому bbb = 000.

Подставляем биты и получаем: 1001 1010 1011 0000 или 0x9AB0

Теперь создадим HEX файл для прошивки микроконтроллера.

Состав HEX файла выглядит следующим образом:

image


Наш HEX-файл будет состоять из двух строк: в первой строке будет прописана двухбайтная инструкция 0x9AB0, а вторая строка будет указывать на окончание HEX-файла.
В качестве адреса, где будет расположена наша команда, выберем нулевой адрес. Хотя, можно выбрать абсолютно любой адрес из всего адресного пространства.
Контрольная сумма вычисляется вычитанием из нуля всех байт строки. Младший байт получившегося значения как раз и является контрольной суммой.
То есть, для нашего случая 0x00 — 0x02 — 0xB0 — 0x9A. Младший байт получается равным 0xB4. Его и вписываем в конец строки.

Последняя строка должна указывать на окончание HEX файла и должна выглядеть следующим образом:

:00000001FF

И так же нужно помнить, что в HEX-файле байты команд поменяны местами. То есть сначала записываем младший байт 0xB0, затем старший байт 0x9A.

Итоговый HEX файл будет вот таким:

:02000000B09AB4
:00000001FF


Записываем получившиеся строки в блокнот и сохраняем с расширением .hex (впрочем, сохранить можно с любым расширением).

Теперь осталось зашить эту прошивку в микроконтроллер, установить тактирование от генератора watchdog таймера и включить деление на 8.

Вот пример настройки fuse-бит в среде Atmel Studio 6

image


Получаем результат в виде мигающего светодиода. Проверено в железе. Исправно мигает.

Таким образом, самая простая программа состоит из двух байт, а самая простая схема – из элемента питания, микроконтроллера и светодиода.

Кто-нибудь напишет программу мигания светодиодом еще короче?
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 84
  • +3
    В вашей программе не 1 команда (2 байта), а 1024 (2048 байт)
    • +45
      Значит, я побил другой рекорд — максимально объемная программа мигания светодиодом для данного микроконтроллера. Кто-нибудь напишет программу еще длиннее?
      • +25
        … как и во всех остальных программах для этого микроконтроллера. Соревнования закончены, расходимся.
        • 0
          В байте не обязательно 8 бит.
          • 0
            не путайте с длиной машинного слова
            • 0
              А он и не путает. Байт — это совокупность битов, обрабатываемая компьютером одномоментно. В стандарте Си определение даже более жёсткое: byte is an addressable unit of data storage large enough to hold any member of the basic character set of the execution environment. Соответственно если компьютер так устроен, что он не может адресовать октеты, то байт там будет другого размера.

              Размер байта задаёт CHAR_BIT, размер машинного слова (по крайней мере теоретически) — sizeof(int) * CHAR_BIT. На некоторых моделях Cray CHAR_BIT == 32, то есть там именно байт имеет такую длину. На некоторых DSP CHAR_BIT == 16.
              • 0
                Вот именно — на некоторых. К мейнстриму это не относится, и тем более к AVR. Замечание формально верное, но тут просто неуместное, тем более к комменту.
                • 0
                  А почему это, собственно, «замечание к AVR не относится»? Я просто не знаю: эта железяка вообще к октетам обращаться умеет? Или только к 16битным словам? Если последнее — то у неё как раз 16-битный байт :-)
                  • 0
                    Вспоминается старый метод описания, применявшийся в 60-70х:
                    «48 разрядное машинное слово». Или «объем памяти — 2048 15 разрядных слов», если минимальная адресуемая единица — 15 бит.
                    • 0
                      Вы не поверите, но на многих встроенных системах и сейчас так всё описывается. Особенно на процессорах гарвардской архитектуры. Конкретно про этот AVR — не знаю, не работал с ним.
                    • 0
                      Тут вы точно попутали байт с машинным словом. Собственно как и вики, в выражении «совокупность битов, обрабатываемая компьютером одномоментно». Лучше английскую страницу откройте.
                      (Реально надо бы поправить текст там, сбивает с толку)

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

                      зы: AVR 8-разрядный МК. Точнее архитектура так и называется AVR8, т.к. у Atmel есть ещё и AVR32, с помощью которой они собирались конкурировать с ARM. Похоже не взлетело…
                      • 0
                        Интересно, если машина оперирует минимум 48 битами, какой у нее байт?
                      • 0
                        Лучше английскую страницу откройте.
                        Открыл. Прочитал: it is the smallest addressable unit of memory. Что там сбивает с толку и кого?

                        И разным он был только на заре вычислительной техники, если верить той же вики, уже с 70х его приняли равным 8 битам.
                        Совершенно верно. В 70е годы большинство распространённых архитектур перешли на 8-битовые байты и в них smallest addressable unit of memory является 8-битовым.

                        Тем не менее архитектуры, в которых байт не 8-битовый по прежнему существуют, просто они ушли в разные специфические ниши.
                        • 0
                          Тем не менее архитектуры, в которых байт не 8-битовый по прежнему существуют, просто они ушли в разные специфические ниши.

                          Я же не спорю, собственно и настройка компилятора вида CHAR_BIT, упомянутая вами, для этого и сделана. Но если бы архитектура были такой специфичной, об этом 100% было бы упомянуто в статье. Спор начался с фразы «в байте не обязательно 8 бит» к комменту «В вашей программе не 1 команда (2 байта), а 1024 (2048 байт)» где даже про биты вообще нет ни слова :)
                          Открыл. Прочитал: it is the smallest addressable unit of memory. Что там сбивает с толку и кого?

                          Не вырывайте из контекста:
                          Historically, the byte was the number of bits used to encode a single character of text in a computer[1][2] and for this reason it is the smallest addressable unit of memory in many computer architectures.
                          Это гораздо точнее, чем в русскоязычном варианте.
                          • 0
                            Не вырывайте из контекста:
                            Historically, the byte was the number of bits used to encode a single character of text in a computer[1][2] and for this reason it is the smallest addressable unit of memory in many computer architectures.
                            А чем вам тут контекст помог? Он раскрывает исторические основы понятия «байт», но суть дела не меняет.
                      • 0
                        Регистры 8-битные, так что формально контроллер 8-битный.
                        • 0
                          Не только регистры важны, но и внешняя шина.
                          • 0
                            Несомненно внешняя шина важна… но в контроллере минимальная адресуемая порция данных имеет размер регистра, иначе всё теряет смысл.
                            • 0
                              Скорее уж внутренняя. Иначе у вас 8088 8-битным окажется. При этом Z80 с его 16-битными регистрами вроде как 8-битным считается. Так что понять сколько битный у вас процессор без электронного микроскопа не удастся :-D
                              • 0
                                Я о том и говорю, как раз про 8088 и думал — он только наполовину 16 разрядный.
                                • 0
                                  Он на все 100% 16-разрядный. У него все «кишки» от 8086, только интерфейс с памятью переделан. Написать программу, которая гарантированно отличит его от 8086 было весьма нетривиально в своё время.
                                  • 0
                                    Вопрос терминологии, забудем.

                                    push sp 286 отличает или 88?
                                    • 0
                                      push sp отличает 186й кажется. Точно не 8088й.

                                      8088й не только логически устроен как 8086й с «буфером согласования с 8битной шиной», он и физически так устроен, потому что-то отличить весьма проблематично, Известный мне надёжный способ — это использование самомодифицирующегося кода. За счёт разного размера буфера 8088 замечает чуть более «близкие» изменения в потоке команд. Но там есть чудеса с выраваниванием и прочее.
                                • 0
                                  А как в Z80 считать из памяти сразу 16 бит? регистры у него не адресуются в общем пространстве и стоят особняком. основная шина — 8-битная, считать что-то большее можно только за два этапа.
                                  • 0
                                    Причём тут считывание из памяти вообще? 80386SX считывает из памяти за раз не более 16 бит, а Pentium — не менее 64 бит, но оба процессора считаются 32-битными. Ибо являются модификациями одной и той же архитектуры.
                • 0
                  Есть такая функция практически во всех новых контроллерах и мегах с индексом A и PA…
                  • 0
                    Да, действительно есть. По крайней мере, в ATmega48A/PA/88A/PA/168A/PA/328/P есть. А вот в ATmega8A/16A/32A эта функция точно отсутствует.
                  • +1
                    В начале было слово, и сказал программист: «да будет код»!
                    • +32
                      Можно моргать светодиодом с контроллера не написав ни строчки кода ;-)
                      Заголовок


                      А вообще круто вы, хардкорно моргаете. :)
                      • +17
                        Или даже вообще не используя микроконтроллер — берём китайский мигающий светодиод и всё :)
                        • +3
                          Мигающий светодиод это не круто, интереснее на транзисторах и никаких контроллеров ;)

                          habrastorage.org/files/3a3/dca/471/3a3dca4714a74390a426ed7ac81844d3.png
                          • –4
                            Транзисторы — это не современно. Только К155ЛА3! Только ТТЛ! :)
                            • +11
                              Если я ничего не путаю, то ТТЛ — это Транзисторно-Транзисторная Логика. И после этого Вы утверждаете, что Транзисторы — прошлый век? :)
                              • –5
                                Не путаете. Просто нужно быть чуть проще и не искать тайный смысл… И чаще улыбаться («Умное лицо — ещё не признак ума» © Тот Самый...)

                                А если уже хотите копаться глубоко, то пишите сразу — «интереснее на элементарных частицах этой Вселенной»…
                            • +2
                              А еще можно просто воткнуть светодиод в розетку через сопротивление 22КОм. Правда он будет мигать с частотой в 50 герц, но это уже мелочи :)
                              • +1
                                можно и так, без полупроводников, elektricvdome.ru/pereklyuchatel-girlyand/ (первая схема)
                                • 0
                                  Моя схема проще :) хотя Ваша больше подходит под ТЗ, да :)
                                  • +3
                                    Проще только дать ключ-переключатель моему соседу алкоголику, когда у него тремор с похмелья.
                                    • 0
                                      Я о таком тоже думал, но это как-то не спортивно получается :)
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                        • +2
                                          Зато легко регулируется уровнем известной жидкости в стакане.
                                  • 0
                                    А его точно не пробьёт обратным напряжением?
                                    • 0
                                      Да, действительно… Значит нужно добавить последовательно еще обычный диод, рассчитанный на 220 вольт.
                                      • +1
                                        Лучше параллельно и любой диод.
                                    • –1
                                      Пардон, открываться он будет только в один полупериод => 25 Гц
                                      • +2
                                        Нет, именно 50
                                        • 0
                                          Точно, перепутал что-то я
                                      • +4
                                        Можно воткнуть в солнечную батарею. Период мигагия примерно одни сутки.
                                      • 0
                                        Моя первая схема :)
                                        Только вместо светодиода была лампочка, вместо 315го МП37, вместо 361го — П217
                                        • 0
                                          Схема — это уже код для аппаратной программы. Причем для АВМ.
                                    • +2
                                      … как два байта переслать.
                                      • 0
                                        Word? Что-то новое. Вроде был Hello World)
                                        • 0
                                          для Hello World нужно слова знать. А тут уровень еще ниже: «да будет слово...»
                                          • +13
                                            Из-за ограничений на длину программы буква «l» не влезла.
                                            • +1
                                              Если точнее, был «Hello, world!».
                                              • +2
                                                Hello Word
                                                Хотел сообщить об опечатке, но потом понял, что это и правда Hello Word :)
                                                • 0
                                                  Да, вчера в час ночи пришла эта же мысль)))
                                                  Не смог спать. Пришлось встать, проверить и дописать в статью.
                                                  • +1
                                                    Со всеми этими минимальными хеллоувордами вспомнились давние соревнования по написанию минимального резидентного вируса под MSDOS. Естественно, никто не выпускал в свободное плавание их, поскольку они бы там долго не прожили. Это было чисто соревнование. Мне же понравилось то, что этот процесс шел годами уже после забвения MSDOS. При этом каждый год удавалось уменьшить то на один, то на 2 байта.

                                                    Когда в 90х ко мне попал текст вируса байт на 120, для меня это было как произведение искусства, но я даже не подозревал что пройдет много лет и его уменьшат в 2(два!) раза.

                                                    Кстати, ходит легенда, что самый маленький резидентный вирус написал Данилов, но никому его не показывал. Интересно бы посмотреть на это произведение искусства.
                                                    • 0
                                                      Уже за гранью условий задачи, но 0 байт возможны!
                                                      habrahabr.ru/post/240517/ UPD3
                                                      • 0
                                                        Микроконтроллеры мне не доступны, но в далеком 95-м году был у меня программируемый калькулятор, если не ошибаюсь ресурсов, 2 регистр, аккумулятор и памяти на 40 команд. Вот это были оптимизации…
                                                        • 0
                                                          Описанный уровень — это что-то странное. ИМХО, у первых в мире программируемых калькуляторов ресурсов было больше. По крайней мере у советского Б3-21 1977-го года было 60 шагов программной памяти и 13 адресуемых регистров и два операционных. А уже у бессмертного Б3-34 1980-го — 98 шагов программы, 14 адресуемых регистров и 4 регистра стека.

                                                          1986-й год — это уже МК-85 на Бейсике с 1221 байтом ОЗУ.

                                                          На этом фоне мне даже сложно представить, какой уровень ПМК должен был быть в 1995-м, я с этой отраслью не связывался с ~1993-го, последним был именно МК-85 :)
                                                          • 0
                                                            МК-61 — аналогично 105 шагов, 15 регистров, 4 ячейки стека. До сих пор пользуюсь.
                                                            • 0
                                                              Отображалось 105 и в инструкции было 105, но реально было 160, просто они не отображались при вводе.
                                                              • 0
                                                                Вы немного перепутали. Шагов там таки было 105. Адресов было больше. Короткая побочная ветвь (с адресов "-5" по «L1») на семь шагов (исполняются команды с адресов «00» — «06») и длинная (с адресов «L2» по «F9») на сорок восемь (исполняются команды с адресов «00» — «47»). Об этом даже в Wikipedia написано! Иногда это использовали как в вышеописанной программе, чтобы не тратить память на команды перехода.

                                                                И да, при попытке «посмотреть» на эти участки в некоторых местах приводили к тому, что там ничего не было видно. Но если туда что-то ввести и посмотреть на «главную ветвь», то изменения «проявлялись». Мечтам о 160 шагах, увы, было не суждено сбыться.
                                                                • 0
                                                                  Да, возможно, могу ошибаться за давностью лет. МК-61 все еще лежит, в комплекте с инструкцией и тетрадкой с переписанными из ТМ программами, но что-то с блоком питания.
                                                            • +1
                                                              Могу предположить, что речь о чем-то вроде этого CITIZEN SRP-45 на 40 программных шагов без ветвлений и циклов. Помню кучу программ под него написал. Даже игру Ним сделал и всех обыгрывал в школе :).
                                                              • 0
                                                                Модель не та, но да это был ситизен, по тем временам просто мечта, мне подарили родители, потому как не могли подарить PC.
                                                                И да 40 шагов без всяких там читерских ветвлений :)
                                                                • 0
                                                                  Сейчас он идет как обновленная версия с новым дизайном — SRP-145N. Приятные цвета, стал потолще а функциональность абсолютно та же, даже угол обзора дисплея и контраст сохранили.
                                                            • 0
                                                              Идея прикольная, но полагаться что вся память будет забита 0хFF нельзя, это не всегда так. Поэтому, к сожалению, программа будет занимать больше места.
                                                              • 0
                                                                После стирания flash — всегда. Если вдруг не случился аппаратный сбой.
                                                                Мы говорим о памяти программ.
                                                                • 0
                                                                  Угу. И что тогда будет с загрузчиком? ;)
                                                                  • 0
                                                                    Автор не использует программный загрузчик.
                                                                    Он стирает flash и заливает программу через SPI.
                                                              • 0
                                                                На днях проектировал простенький AVR микроконтроллер на ПЛИСе. Программа пишется в AVR студио на ASM, потом вливается в плис. www.youtube.com/watch?v=lavcU7kF4Ng

                                                                Тут увидел эту статью… Так вот «программа для мигания светодиодом на AVR микроконтроллере» у меня получилась 1-й командой размером в 14 битов) Она инвертирует биты в регистре ножек порта. Ну а скорость мигания можно настроить делителем.
                                                                • 0
                                                                  А переключить порт на вывод? тоже ведь команда нужна…
                                                                  • 0
                                                                    А он не выводит в порт.
                                                                    • 0
                                                                      инвертировать биты порта (регистра) это и есть вывод в порт. По дефолту они в лог. '0', т. к. регистр 8b00000000
                                                                      • 0
                                                                        Вывод в порт это:
                                                                        in R16, PORTB
                                                                        com R16
                                                                        out PORTB, R16

                                                                        А вот это не вывод в порт:
                                                                        com PORTB
                                                                        • 0
                                                                          Да, я понял о чем вы. У меня просто этот вывод идет не в коде программы, а в алу. Операнд источник- Port0, операнд приемник- Port0, операция- побитная инверсия. Результат выводится в порт.
                                                                    • 0
                                                                      У меня по дефолту 1 порт на вход и 2 порта на выход.
                                                                      Могу их сделать bidirectional, но конфигурация все равно не нужна будет.
                                                                      • 0
                                                                        это уже нестандартное железо, его конфигурация уже является частью программы. Так можно дойти до того что реализовать программу на частном случае вычислительной машины — однобитная, способная выполнять всего одну команду, которая оптимизируется до обычного счетного триггера.
                                                                        • 0
                                                                          Ну знаете что, заполнять всю память 0xFF при стирании а потом дописывать 2 байта это тоже «нестандартное железо». Программа то без стирания работать не будет. Так что всё можно опровергнуть, и топикстартера тоже если на то пошло.

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