Эксперимент с прикручиванию к дешевым микроконтроллерам ATTiny загрузчика и среды разработки Arduino был достаточно удачным. Конечно, с AVR неплохо живется и без Arduino. Но хорошо, когда есть возможность выбора. А потом я вляпался в STM32 и заковырялся в библиотеках и громоздких конструкциях инициализации портов. Спасением ARM-«чайника» стал проект ARM mbed. Лично мне он позволил просто взять и начать работать с STM32.
Но мигать светодиодом на плате Nucleo надоело очень быстро. Отложил я ее, ибо слишком много ножек и наворотов, и взялся за Maple Mini (STM32F103CBT6 с минимальной обвязкой). Тоже все довольно легко и просто — сервоприводы крутятся, датчики работают, экранчики показывают — все популярные библиотеки, знакомые ардуинщикам, в mbed имеются.
А третий заход отчасти повторял «Arduino за 1$». О нем я и расскажу подробно. Идея такая: хочу ARM за копейки. Открываю Aliexpress и нахожу STM32F030F4P6 за 55 центов за штучку при покупке пучка (10 чипов).
Данный чип кажется весьма неудобным для кустарного использования, поскольку выполнен в корпусе TSSOP20. Но это даже интересно, поскольку DIP-корпуса распаивать уже скучно, а сверлить отверстия в плате — лениво. Можно, кстати, использовать переходные платы TSSOP-DIP, но пока я ждал заветный китайский пакетик, сделал свою.
Помимо самого контроллера, на платке (односторонней) размещаются кварцевый резонатор, два конденсатора, три резистора и один джампер. Отдельно выведены пины для подключения отладчика. Стабилизатор напряжения питания ставить пока не стал, поскольку устройство сугубо тестово-демонстрационное, для коллекционирования граблей и как proof of concept. Главное — не подать 5 вольт питания.
Mbed не поддерживает «из коробки» STM32F030F4P6, ближайшим родственником будет Nucleo-F030R8. Эта плата и выбирается как целевая платформа. А модифицированную версию библиотеки mbed добрый человек уже сделал. Так что, здесь обошлось без неприятностей.
Испытания
Тут, по идее, должно было быть восторженное описание процесса портирования легендарного Blink. Но нет, пусть тест будет немного посложнее, тем более, что автор модифицированной библиотеки пишет, что работа SPI не протестирована. Так что, собираю на «хлебной» макетке конструкцию из платы, китайского OLED-дисплея (128х64) и модуля питания, подключаю самопальный ST-Link (в корпус я его так и не засунул, но хотя бы нужные элементы напаял непосредственно на плату) и собираю из кирпичиков код прошивки.
Кирпичики такие:
1. Модифицированная библиотека mbed. Не забываю удалить из проекта дефолтную.
2. Библиотека SSD1306 — для работы с дисплеем. Я в нее добавил русский шрифт (коды стащил отсюда), но в данном проекте не применял, ограничившись выводом растрового изображения.
3. Примитивнейший main.cpp.
Растровое изображение подготовлено с помощью утилиты LCD Assistant. Полезнейшая в хозяйстве вещь, скармливаешь ей однобитный bmp-файл, а она выдает в текстовом виде байтовый массив, пригодный к употреблению в C.
А дальше все почти как в Arduino:
/*
Китайский 0.96 128х64 OLED.
SPI_MOSI=PA_7 SPI_MISO=PA_6
SPI_SCK =PA_5 SPI_CS =PB_6
SPI_CS нет в STM32F030F4, используем PB1
*/
#include "mbed.h"
#include "ssd1306.h"
#include "standard_font.h" // высота 8, ширина 6 (21 столбец)
#include "bold_font.h" // высота 8, ширина 8 (16 столбцов)
#include "russian_font.h" // experimental
// настройка LCD Assistant: Byte orientation - horizontal, остальное по дефолту
const unsigned char habr [] = { массив я удалил, чтобы место не занимать };
SSD1306 oled(PB_1 /* cs */, PA_4 /* reset */, PA_3 /* dc */, SPI_SCK /* clock */, SPI_MOSI /* data */);
int main()
{
oled.initialise();
oled.clear();
oled.set_contrast(100); // 255 max contrast
oled.drawBitmap(0, 0, habr, 128, 64, 1);
oled.update();
}
// EOF
Компилирую, скачиваю бинарный файл прошивки, заливаю в контроллер с помощью ST-Link Utility и получаю требуемый результат. К сожалению, проблем, достойных описания, не возникло.
Впрочем, начудить я умудрился — два раза ошибся в разводке платы. Зачем-то подтянул NRST (сброс, активный уровень — низкий) к земле. И расстояние между гребенками сделал такое, что плата в макетку нормально не вставляется, только с приложением пары ласковых и физической силы.
Итого
Бюджетнейший 32-битный ARM-микроконтроллер STM32F030F4P6 стоит чуть более половины доллара. При этом — 4 килобайта оперативной памяти и 16 — флеша. Обвязка — наверное, еще рублей 20, но ее можно сократить, убрав все «лишнее» вокруг пина BOOT0. Среда разработки mbed намного проще в освоении новичку, если сравнить с теми же IAR, Keil или Coocox, но при этом не страдает чрезмерным примитивизмом Arduino IDE. К тому же, на локальном компьютере нужно установить только ST-Link Utility, исключается возня с компиляторами.
Резюмирую: очень понравилось. Считаю возможным и нужным рекомендовать mbed для освоения новичкам в области микроконтроллеров. Паять TSSOP не обязательно, можно приобрести плату Nucleo или любую другую поддерживаемую, вплоть до дешевых «минимальных» китайских поделок за 3.8$.
Комментарии (26)
svd71
28.05.2015 09:35Для меня такие железки только хобби. Чесно говоря и чип понравился, но есть довольно жирная ложка дегтя: отсуствие симулятора.
При проектировании схематики в протеусе и интеграции его с авр-студио разработка превращается в удовольствие с возможностью пошаговой отладки. Потому как в Протеусе можно и дополнительную обвязку протестировать. Может я, конечно, обленился, но купленные пучком на алиекспрессе меги8 у меня еще не закончились. И судя по всему с таким симулятором будут еще долго использоваться.
Хотя, при заимении другого удобного тулчэйна и дешевых чипов с лучшими характеристиками, с удовольствием переползу.TimReset
28.05.2015 11:20А как у вас обвязка в Протеусе работает в плане соответствия реальным данным? Я читал, что Протеус для моделирования аналоговых схем не очень подходит — он больше по микросхемам. Не могли бы Вы привести пример проекта с обвязкой? Сам я пробовал в Протеусе моделировать — в нём всё работало, а в железе — нет. Хотя тут может мои незнания повлияли — сам я больше по ПО, чем по железу :) И вообще, может статью напишете по разработке в Протеусе, а потом воплощение в железе? :)
svd71
28.05.2015 16:01+1На самом деле моя работа в нем занимает первоначальный вариант. До сборки в железе. И не стоит забывать, что это небольшие любительские поделки, по большей части состоящие с микроконтроллером — проще сказать концептуальная модель. Там хвалиться особо не чем.
Допустим я делаю с детьми робота на сервах. И мы с ними придумали новый метод обработки нескольких серв. Первым делом делается модель в протеусе с этими несколькими сервами и там исследуется.
Потом вот заказываем, допустим, Keyjoys(аналог джойстика от PS). Изучаем модель управления джойстиком команд с выводом в терминал UART. При такой разработке понадобилось несколько кнопок прикрутить и не забыть сделать вывод на радио-мудиль по SPI. На каждом этапе можно посмотреть как будет вести себя программа и реагировать собранная система. При этом еще реальных железок нет.
На такие самоделки точность обычно никчему — я ведь не сердечный стимулятор изобретаю. Зато сокращен до минимума процесс работы и отладки с реальным железом. Когда этим делом занимаешься профессионально — то есть в основное время, то вырабатываются некоторые небxодимые рефлекс — допустим, всегда проверить напряжение. Но когда такое дело хобби и есть обязательства перед семьей, то такие изыски в свободное время чреваты горелыми кристаллами.
И кроме того, пытливые детские умы могут в мое отсуствие проверить какую либо электронную гепотизу, исключая вероятность того, что будет испорчен как минимум компьютер. А как максимум пожар или поражение электротоком.
что касается воплощеня в железе, то чато обхожусь растровой платой. Хотя бывает заЛУТиваю что либо на текстолите. Сейчас вот фоторезист хочу попробовать — уже и УФ лампочку прикупил. А если и проектирую такую плату, то в Eagle CAD-soft, a совсем не в Протеусе. Это обуславливается большей свободой в разработке футпринтов. Да и часто проще найти в сети уже готовый элемент.
eta4ever Автор
28.05.2015 11:38Я на Протеус не полагаюсь. Да, он моделирует AVRки, это прикольно. А вот если к ним подключено что-то сложнее светодиода, то начинаются чудеса. Вот, например, пытался я моделировать схему управления из предыдущей публикации. Местами работало, местами получалась откровенная хрень.
Int_13h
28.05.2015 12:18Да ладно, Протеус — удобный инструмент, только надо пользоваться правильно и не желать невозможного. А использование инструментов сильно облегчает жизнь инженера.
eta4ever Автор
28.05.2015 13:12Я не спорю, что это очень крутая и полезная штука. Но всецело полагаться на него тоже нельзя. Я сталкивался как с тем, что в Proteus схема работает, а в железе — нет (при 100% совпадении деталей), и с обратной ситуацией — тоже.
svd71
28.05.2015 16:08Есть такой момент. Но связан о часто с невнимательностью в мелочах: фьюзы неправильно выставленны, некоторые ноги по умолчанию в симуляции себя ведут по другому, чем с железом (например непдключенный AVCC у АВРок приведет к неработе порта С, хотя в симуляции все прекрасно).
eta4ever Автор
28.05.2015 16:14Я по большей части про аналоговые вещи. С симуляцией собственно AVR у меня все хорошо было, в том числе что касается ЦАПа и компаратора.
svd71
29.05.2015 11:59+1Аналоговые элементы тоже пробовал, но не настолько уж с микроконтроллерами связаными. Два или три раза с операционниками расчитывал. но больше интересовала форма искревления сигнала в виртуальном осцилографе (увы, только у друга есть профессиональный генератор, но тащить его ради одной поделки желания не было).
И раз считал H-Bridge для микромотора на имеющихся в наличии биполярниках. Потом это дело решил в Протеусе обкатать с теми же значениями. Схема не завелась. Пришлось изменять параметры сопротивлений. В железке с новыми значениями тоже не заработало, зато с ранее расчитанными очень даже начала работать.
kibergus
28.05.2015 21:19Зато с stm32 можно делать пошаговую отладку на реальном железе. А с avr… тоже можно, но когда я в последний раз смотрел, за это удовольствие надо было заплатить совсем негуманные деньги.
sguwenka
28.05.2015 10:43+3Растровое изображение подготовлено с помощью утилиты LCD Assistant. Полезнейшая в хозяйстве вещь, скармливаешь ей однобитный bmp-файл, а она выдает в текстовом виде байтовый массив, пригодный к употреблению в C.
Простите, не могу с этим согласиться. На выходе получаются нечеловеко-читаемые массивы. Изменить картинку в паре мест, изменить любой другой ресурсный файл — и снова всё конвертировать? спасибо, не надо.
Отработал для себя следующий вариант.
1. В makefile проекта создаётся цель convert, должна входить в зависимость для цели исполняемого файла. Цель представляет любые входные файлы (ресурсы) в виде бинарных объектников:
all : ... $(MAKE) convert ... convert: @echo --- start objcopy... $(OBJCOPY) -I binary -O elf32-littlearm -B arm html\ethernetindex.txt html\ethernetindex.o $(OBJCOPY) -I binary -O elf32-littlearm -B arm html\arsenal.gif html\arsenal.o $(OBJCOPY) -I binary -O elf32-littlearm -B arm html\ascii_girl.txt html\ascii_girl.o @echo --- done...
2. В скрипт линкера *.ld добавляются эти объектники. Если файлы вызываются редко, то в секцию .text. Можно и в .data, если скорость важна или динамическое изменение содержимого подключенных файлов:
.text : { ... *(.text) /* remaining code */ *(.text.*) html/arsenal.o html/ethernetindex.o html/ascii_girl.o ... }
3. При включении файлов в проект, при линковке в сгенерированном map-файле можно найти, какого вида сформировались ссылки для подключенных ресурсов (для этого в *.ld надо прописать KEEP(html/arsenal.o) в первый раз, если в коде нет ссылок на ресурс). Например:
html/arsenal.o() .data 0x0800abd8 0x69b html/arsenal.o 0x0800abd8 _binary_html_arsenal_gif_start 0x0800b273 _binary_html_arsenal_gif_end
Кроме того, в том же map-файле или в файле определений символов можно найти ещё сгенерированные константы:
*.sym: 0000069b A _binary_html_arsenal_gif_size *.map: _binary_html_arsenal_gif_size html/arsenal.o
4. Сгенерированные ссылки и константы являются глобальными, и мы можем использовать их в своих си-файлах:
extern char _binary_html_arsenal_gif_start; extern char _binary_html_arsenal_gif_end; char *arsenal_start = &_binary_html_arsenal_gif_start; char *arsenal_end = &_binary_html_arsenal_gif_end;
Более того, если у вас файл имеет определённую структуру, то можно делать ссылку на структуру (файл распологать в секции .data!) и потом динамически обновлять содержимое файла через поля структуры… В общем у кого на что фантазии хватит.
1 раз повозиться с настройкой проекта — зато потом можно «на лету» подключать/изменять любые ваши ресурсы!Vooon
28.05.2015 11:15+1А зачем добавлять обьектники в ld, разве не достаточно включить их в список обьектников для линковки?
Думаю что секцию можно указать objcopy.sguwenka
28.05.2015 11:28Можно, наверное! Не думал об этом ;)
objcopy --add-section .text.rc*
как-то так наверное, в синтаксисе не уверен — надо проверять.
eta4ever Автор
28.05.2015 11:35+1Спасибо за совет. Но это немножко другой уровень. На текущем мне не нужно вообще знать, что существует Makefile и какая-то линковка. Ну, то есть, я изображаю процесс «ардуино-стайл».
barabanus
28.05.2015 12:00На выходе получаются нечеловеко-читаемые массивы.
А в вашем случае — человекочитаемые?eta4ever Автор
28.05.2015 12:07Если надо прямо-таки читаемые, то надо реализовывать файловую систему, в нее класть ресурсы, и обрабатывать их программно. Ну, это не совсем та задача, которую хотелось бы решать при наличии 16 килобайт флеша.
sguwenka
28.05.2015 12:11Вообще-то да, т.к. создание объектников происходит на стадии компиляции всего проекта. А до этого момента работа может вестись напрямую с самим ресурсом.
burjui
28.05.2015 15:40+2Если у вас много таких ресурсов, то вместо того, чтобы писать каждый раз
$(OBJCOPY) -I binary -O elf32-littlearm -B arm html\xxx.gif html\xxx.o
Лучше сделать так:
.SUFFIXES: .txt .gif .o .txt.o: $(OBJCOPY) -I binary -O elf32-littlearm -B arm $< $@ # аналогично для gif
после чего просто добавить объектники в список и внести объектники в зависимость:
OBJECTS = main.o ethernetindex.o arsenal.o ascii_girl.o all: $(OBJECTS) ...
Тогда make соберёт ресурсы автоматически при сборке цели all и не будет собирать ресурсы каждый раз заново, если исходные txt и gif не менялись.
random1st
28.05.2015 16:10Чем mbed лучше того же STM32Cube? Там в принципе HAL тоже достаточно высокий уровень абстракции обеспечивает, да и работать с ним вроде как не так и сложно.
eta4ever Автор
28.05.2015 16:16Тем, что mbed — это не просто генератор проекта, а комплекс из IDE, репозитория библиотек и компилятора. С возможностью, кстати, экспорта в проекты «настольных» IDE (не проверял). И уровень абстракции еще выше. Что не умаляет достоинств Cube.
abrakada
А какое энергопотребление у этого дисплея? Я вот тоже парочку заказал таких же с алиэкспресса, а сейчас собираюсь аккумуляторы подбирать, так что информация бы пригодилась.
eta4ever Автор
Напрямую зависит от количества зажженных пикселей. Я не мерял, но Adafruit говорит, что стоит рассчитывать примерно на 20 мА.
abrakada
Это в среднем или на какое-то определенное количество пикселей?
eta4ever Автор
Скорее, максимум. Видел упоминание сейчас, что примерно 20 мА при полностью зажженном дисплее.
abrakada
Спасибо, вы меня обнадежили
assad77
я измерял потребление у себя на 1.3 spi oled дисплее при заженных 10-20% пикселей (те выведен только текст.)
да, получилось около 20мА.