2 года назад я увидел запись «Предел минимального Hello Word на AVR составляет 2 байта» на Habrahabr`е пользователя swap_map с подначиванием в конце:
Кто-нибудь напишет программу мигания светодиодом еще короче?

Тогда я посчитал, что это просто невозможно, но сейчас я смог это сделать.



Наверное, стоит сказать, что мой способ написать такую прошивку несколько нестандартный, потому что по факту прошивки нет, есть только форма оформления пустого *.hex файла. Содержимое *.hex считанного с пустого (после операции chip erase микроконтроллера atmega328p выглядит следующим образом: :00000001FF. Позволю себе использовать изображение из статьи swap_map для наглядного сравнения. Красной рамкой обвёл код, который необходим для моего примера минимального Hello word.


Зажигать я буду светодиод на разряде 0 порта b и только его. Частота мерцания будет равна 16 кГц, для того, чтобы удостовериться в том, что ножка всё же дрыгается, собрал следующую схему. Внимание: Напряжение на аноде светодиода верхнего плеча должно быть меньше суммарного параметра Forward Voltage для данных светодиодов, иначе они замкнут собой шину питания и, наверняка, сгорят или сильно деградируют. В моём случае напряжение на аноде было 3.2В.



Симуляцию в протеусе данная схема в исходном варианте (с пустой прошивкой) не проходит, протеус жалуется на некорректный opcode. Не беда, соберу в железе. Слева крокодилы осциллографических щупов, справа шлейф программатора USB ASP, от конденсатора и дальше по макетке — другой проект.



Как же оно моргает? А моргает оно через настройку FUSE битов. В ATMega328p и в некоторых других avr мк есть бит называемый CKOUT, при выставлении которого осуществляется вывод тактовой частоты на пин 0 порта b. При этом источник тактирования совсем не важен: внутренние RC цепочки, внешний кварц или вообще входящий тактовый сигнал — всё это пойдёт в порт. В качестве источника тактирования я выбрал внутреннюю RC цепь с частотой 128 кГц с делителем на 8. Поэтому итоговая частота и будет 16кГц. В итоге фьюзы выставлены так: hf=DB, lf=13, ef=07. Красной рамкой обведён тот самый бит.


Ну и что, работает? Да, на фотографии макетной платы выше видно, что светятся оба светодиода, но как то это не очень наглядно. Подключим моего старичка с1-49 и посмотрим состояние пина 0 порта b:



Период в 60 мкс даёт нам частоту немного более 16 кГц, но период на фото не дотягивает до 60, частота выходит больше, спишу это на почтенный возраст и очень давно сделанную калибровку. Можно считать, что результат достигнут.

Надеюсь, данная запись заставит некоторых людей хотя бы бегло просматривать возможности конфигурации используемых МК с помощью FUSE битов.
А теперь моя очередь говорить: «Кто напишет программу мигания светодиодом короче?»
Поделиться с друзьями
-->

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


  1. sintech
    27.10.2016 19:48
    +9

    Это читерство ;). Фьюз биты — тоже биты и влияют на функционирование контроллера. Это как если бы вы вызвали готовую подпрограмму мигания светодиодом из ПЗУ одной строчкой, вместо нескольких в основном коде.


    1. NikitosZs
      27.10.2016 19:54
      +7

      Так же можно и сказать про предыдущий «рекорд», что вызывать спец.функцию для смены состояния порта это читерство. Если есть возможность, то почему ей не воспользоваться?


  1. gbg
    27.10.2016 19:53
    +11

    С вами автор первой статьи. Я рад, что сподвиг коллег на соревнование такого масштаба, что аукается уже второй год как.

    Hello World — это программа, реализующая максимально наглядный «первый раз» в данной среде обитания программиста.

    Для восприятия вашего приветствия потребуется осциллограф, либо динамик + здоровый слух (не все слышат 16 кГц).

    Более того, тут требуется программировать FUSE, а это чревато окирпичиванием контроллера. Я бы на «первый раз» проделывать такое постеснялся.

    Тем не менее, я дополню свой старый пост вашим решением. Спасибо!


    1. NikitosZs
      27.10.2016 19:56
      +2

      Это вам спасибо! Я не стал искать первоисточник этой гонки, поставил ссылку лишь на запомнившийся мне.


    1. vvzvlad
      29.10.2016 02:00

      Более того, тут требуется программировать FUSE, а это чревато окирпичиванием контроллера. Я бы на «первый раз» проделывать такое постеснялся.

      Как, блин, КАК его сейчас можно случайно окирпичить? Я понимаю еще во времена программатора громова и всяких ponyprog можно было запутаться в галочках. Но сейчас достаточно ввести в гугле Fuse calc, выбрать там нужные параметры из меню(даже русские переводы есть), а потом вставить строчку аргументов в avrdude. Чтобы при такой схеме окирпичить — надо тыкать во все пункты, не понимая что они означают.


      1. NikitosZs
        29.10.2016 03:41

        А в бёрномате, откуда у меня скриншот, вообще стоит защита от дурака. Нельзя ни ресет отключить, ни SPI программирование. Но защиту можно выключить.


  1. lart
    27.10.2016 20:05
    +1

    Можно настроить контроллер фьюзами на внешнее тактирование и подать несколько герц. Тогда мигание светодиода будет видно визуально.


    1. NikitosZs
      27.10.2016 20:05
      +2

      Можно, но это уже будет не то.


    1. Iv38
      28.10.2016 02:22
      +10

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


  1. Shamrel
    27.10.2016 21:12
    +1

    Вы по сути используете аппаратную фичу, а это уже не программирование. С тем же успехом, можно было снять частоту непосредственно с кварца и усилить транзистором. «Hello Word» должен быть криком новорожденного ребенка, а не стоном его мамочки.


    1. NikitosZs
      27.10.2016 21:33
      +3

      Открою секрет, все команды используют те или иные аппаратные фичи.


  1. booblick
    27.10.2016 21:28

    такое моргание светодиодом можно и совсем без МК сделать, нужно только два элемента «НЕ».


    1. NikitosZs
      27.10.2016 21:30
      +5

      Зачем 2? Можно и без логики вообще, кнопкой или зубами провода сжимать.


      1. booblick
        27.10.2016 21:50
        +1

        с частотой 16 кГц?


        1. NikitosZs
          27.10.2016 21:57
          +6

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


        1. Grox
          28.10.2016 16:04
          +1

          16КГц? Без логики? Легко. Диск с ручкой для вращения, на нём нанесённые контактные площадки лучами в 0,01125 градуса. Крутим, моргаем.

          Это если за 1 секунду оборачивать. А если делать несколько оборотов в секунду, то можно и меньше площадок поставить.


  1. LampTester
    28.10.2016 17:30
    +5

    Нет, коллеги, я протестую. Я понимаю, что возможны вариации, но считаю, что микроконтроллерный «Hello, World!» это, в силу устоявшейся традиции,

    а) мигание с частотой, заметной глазу — потому что самая простая программа имеет цель быть доступной для наглядной демонстрации с минимальными аппаратными средствами, без всяких осциллографов и прочего;

    б) мигание, являющеется результатом выполнения программы процессором — потому что «Hello, World!» это исторически способ пояснить базовый синтаксис некоторого языка программирования.

    Здесь мигание совсем не мигание, а выдача некоторого сигнала, требующая для анализа дополнительного оборудования. И кроме того, нет выполнения простой программы — непременного атрибута «Hello, World!». А так, я тоже в курсе про CKOUT (он же MCO на STM32, например), но применять его для таких целей я не считаю корректным.


  1. jaiprakash
    28.10.2016 18:11

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


  1. cjbars
    28.10.2016 19:02

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