![]() |
![]() |
|||||||||||||||
Темброблок - анализатор спектра на STM32F103
Автор: WiseLord Немного истории. В 2013 году был разработан первый вариант темброблока с анализатором спектра на ATmega16. В качестве аудиопроцессора в нём использовался оный от Philips - TDA7439. Спектр аудиосигнала и все нужные необходимые регулировки отрисовывались на монохромном графическом дисплее разрешением 128x64 на контроллере KS0108. Устройство было принято довольно тепло, появились запросы на расширение функционала. В частности, уже на этой базе появилась поддержка подобного дисплея, но на ST7920, вариант "для бедных" на символьном 16x2 дисплее. В качестве аудиопроцессора стало можно использовать TDA7313 и TDA7318. Но дальнейшее развитие в рамках ATmega16 стало невозможным. Прошивка перестала влезать в 16кБ Flash-памяти МК, да и архитектурно код не задумывался для такого расширения. Поэтому через два года был создан второй вариант темброблока, уже на ATmega32. Код был написан фактически с нуля, но так как распиновка ATmega32 и ATmega16 одинакова, то обновление в железе было минимальным. В новом устройстве появилась поддержка других аудиопроцессоров, FM радио, таймер отключения, будильник и прочее. Но и здесь в конце концов получилось так, что дальше развиваться стало сложным. Всё-таки на 128x64 разрешении далеко не уедешь. Да и 32кБ ATmega32 тоже как-то быстро стали заканчиваться. Поэтому стали появляться мысли перейти с 8-битного МК на 32-битный. И вот, год назад, я решился таки начать процесс портирования на STM32. Заодно, и начать изучать это семейство, с которым ранее не работал. В качестве микроконтроллера используется STM32F103CBT6, имеющий 20кБ ОЗУ и 128кБ памяти программ. Однако, более популярный STM32F103C8T6 с большой вероятностью тоже будет работать. Хотя у него официально 64кБ флеш-памяти, но на самом деле её там вдвое больше. По крайней мере, те C8T6, которые я покупал в Китае для проекта, равно как и те, что установлены на двух имеющихся у меня платах BluePill, именно 128кБайтовые. Правда, прошивку более 64кБ в них может залить не любая программа, но это уже технические тонкости. И вот, через почти год ленивой разработки по вечерам, получилось что-то, чем уже можно пользоваться. Основной функционал работает, но пока ещё не все функции были портированы. На момент публикации данной статьи готов следующий функционал:
Некоторый функционал пока ещё не реализован. Например, управление по Bluetooth или будильник. Но схемотехнически всё это запланировано и функционал этот обязательно будет добавлен. Просто пока вполне можно пользоваться устройством и без него. Итак, после небольшого обзора основных возможностей, переходим к технической части. Начнём с принципиальной схемы. На ОУ MCP602 (U1 на схеме) собран каскад согласования аудиовхода с АЦП микроконтроллера. Переменный входной сигнал преобразуется в таковой со смещением в половину питания (смещение задаётся делителем на R6/R7). При отсутствии сигнала на входах АЦП будет 1,65В. Подстроечными резисторами RV1/RV2 желательно добиться такой ситуации, чтобы при "обычном" уровне сигнала не было его ограничения по питанию на выходах ОУ. Тогда не будут появляться паразитные гармоники, выглядящие как кратные основной частоте столбики на спектрограмме. На транзисторе Q1 собран небольшой каскад, задающий режим загрузки. По умолчанию, если ничего не трогать, то при включении BOOT0 = 0 и BOOT1 = 1, и МК просто начинает выполнять прошивку при включении. Если же подавать питание, предварительно нажав кнопку BTN_2, то BOOT0 = 1 и BOOT0 = 0, и МК выполняет встроенный загрузчик, что позволяет прошивать плату по UART1. Это удобно делать при отсутствии программатора типа JLINK или STLINK, тогда как USB-UART преобразователи есть, наверное, у всех, кто работает с МК. Модуль питания - обычный линейный стабилизатор AMS1117 на 3.3В (U3 на схеме). Внешнее питание предполагается равным 5В, к нему же подключены подтягивающие резисторы шины I²C. Y1 - кварцевый генератор на 8МГц, обеспечивающий основной тактирование МК. С внутренним умножителем рабочая частота МК равна 72МГц. Y2 - часовой кварц на 32768Гц, обеспечивающий работу встроенного в STM32 блока RTC (часов реального времени). В отличие от проекта на AVR, здесь не требуется отдельная работающая по I²C микросхема RTC типа DS1307 или DS3231. Очень важный момент по часовому кварцу - он должен быть с нагрузочной ёмкостью не более 7пФ, что чётко прописано в соответствующих даташитах. Чаще встречаются кварцевые резонаторы на большую нагрузочную ёмкость, например, 12.5пФ. Так вот, их лучше не ставить. Велик шанс того, что часы не заведутся вообще или будут идти очень нестабильно, чуть ли не вдвое медленее необходимого, причём ход будет зависеть от любых наводок. Я в своё время достаточно помучился с этим (на популярной плате BluePill c STM32F103C8B6 стоял неправильный кварцевый резонатор). J3, J5 и J6 - разъёмы аппаратных UART микроконтроллера. На момент написания статьи в качестве UART пока не задействованы. Но в будущем к ним планируется подключать разные блоки (например, HC-05 для управления по Bluetooth), так что желательно эти разъёмы иметь на плате. По J4 устройство подключается по USB к компьютеру. Практический совет - не подключать 5В линию USB, а использовать только 3 провода. Тем самым не будет конфликта "компьютерных" 5В и питающего напряжения. Также это упростит определение устройства по USB компьютером при подаче или отключении питания. Разъём J7 служит для подключения ИК-приёмника типа TSOP1738 или любого похожего. К разъёмам J13..J15 подключаются аудиопроцессор, тюнер или прочие устройства, работающие по I²C шине. HW_RST линия на J15 нужна в случае выбора в качестве тюнера Si4703, которому для нормальной инициализации нужен отдельный сигнал сброса. Разъёмы J16..J18 - пока незадействованный аппаратный SPI. Три разъёма на схеме потому, что разработанная плата рассчитана на три разных размера SPI дисплея, а SPI шина на них разведена на SD-карту. Каких-то планов как-то использовать SD-карту нет, но соединение сделано на всякий случай для большей универсальности. Линии MUTE/STBY - выходы непосредственно МК. В ждущем режиме на них обеих уровень 0В. При включении устройства сначала логический уровень единицы (3.3В) появляется на выходе STBY, которым через, например, реле можно подать питание на УНЧ. Через некоторое время логическая единица появляется на выходе MUTE, одновременно аудиопроцессор начинает выдавать звук на УНЧ. При отключении (выходе в ждущий режим) MUTE и STBY выключаются в обратной последовательности, что может помочь избавиться от щелчков в динамиках. Очень часто интегральные усилители сразу имеют подобные входы MUTE/STBY, и можно подключаться и к ним. Только надо иметь, что 3.3В активного уровня может быть недостаточно для УНЧ и, возможно, нужно ставить дополнительную схему согласования уровней. Так, например, у популярной TDA7293/TDA7294 для включения на её входах MUTE/STBY должно быть не менее 3.5В. Кнопки (6 штук) и энкодер (линии A и B) подключаются через резисторы параллельно линии данных дисплея. Это позволяет не расходовать лишние пины МК. Работает это следующим образом. Большую часть времени порт данных находится в режиме входа. Когда в дисплей нужно что-то записать, МК сначала считывает состояние на шине данных. Оно будет соответствовать тому, какие кнопки нажаты и как вращается энкодер. После этого шина переводится в режим выхода, МК выставляет на шине нужный байт данных, и пишет (стробом на WR) данные в дисплей. После этого на шине выставляется 0xFF, чтобы вытянуть все линии в единицу и МК переводит снова переводит порт в режим входа. Резисторы 1кОм (R12-R19) нужны для того, чтобы когда МК что-то пишет в дисплей, не получилось КЗ от нажатых кнопок, что привело бы к, как минимум, глюкам в изображении. Дисплей может подключаться по SPI (разъём J12) или 8-битной шине (разъёмы J19..J22). Приведённая схема рассчитана на универсальную плату, позволяющую подключить наиболее популярные модели таких дисплеев. На рисунке справа - 2.4" и 3.2" SPI-дисплеи на ILI9341, а слева - 3.97" дисплей с 8-битной шиной и разводкой "под Arduino". Схема и плата были созданы в Kicad. Такой получился 3D-рендер платы: Платы были заказаны для изготовления на заводе JLCPCB в Китае. Где-то через полтора месяца (белорусская почта как раз очень плохо работала в связи с переходом на новое ПО) платы, наконец-то, были получены: Детали были запаяны на свои места: После сборки "бутерброд" платы и дисплея выглядит следующим образом: Для прошивки и отладки я использую китайский клон STLINK-V2, работающий через двухпроводной SWD интерфейс. На схеме это разъём J2, в котором SWD совмещён с линиями MUTE и STBY. Режим работы этих выводов (SWD или GPIO) выбирается через меню настроек. На момент написания статьи, для упрощения отладки, MUTE/STBY линии временно перенесены на разъём J6 (UART3). Когда недостающий функционал будет дописан, они вернуются на своё место, как на схеме, освободив тем самым UART3 интерфейс. Управление устройством довольно похоже на таковое в предыдущем проекте. Краткое описание функционала энкодера и кнопок: Энкодер: Очевидным образом служит для настройки активного аудиопараметра, а также для навигации в меню. В режиме редактирования радиостанции позволяет выбрать очередную букву названия. Кнопка 0: Переход из ждущего режима в рабочий и наоборот. В ждущем режиме на пониженной яркости отображается текущее время: Кнопка 1: Короткое нажатие перебирает по кругу доступные входы (у TDA7439, например, 4 стерео входа, у PT2313 - один 5.1-канальный и 4 стерео). Длинным нажатием кнопки 1 можно вызвать на экран часы и затем настроить время. Кнопка 2: Основной её функционал - "Отмена". Например, в меню это будет выходом по иерархии наверх. При редактировании имени радиостанции - отмена редактирования и т.п. В режиме FM-радио длинное нажатие вызывает диалог редактирования названия радиостанции, а повторное - стирание радиостанции из списка ранее сохранённых Кнопки 3 и 4: Основной их функционал - навигация "Вперёд" и "Назад" соответственно. Если выбран вход "Тюнер", то эти кнопки будут отвечать за переключение радиостанций (или сканирование вниз и вверх по диапазону, в зависимости от настроек режима работы радио). Если выбран вход "Компьютер", то эти кнопки по USB будут отсылать команды плееру на компьютере для переключение на предыдущий или следующий трек. В будущем (пока не реализовано), если выбран вход "Bluetooth", то эти кнопки будут точно так же переключать треки, которые по Bluetooth транслируются на усилитель, наподобие того, как работают кнопки у гарнитур. В меню кнопки 3 и 4 позволяют производить навигацию по меню, а на экране времени - переключаться между настраиваемым параметром (часы/минуты и т.д) Кнопка 5: Основной функционал - меню/ОК. В рабочем режиме выбирают аудиопараметр для регулировки (Громкость - тембры НЧ/ВЧ и т.д). При навигации в меню активируют выбранный пункт меню. В ждущем режиме длинное нажатие кнопки 5 вызывает меню настроек. Самая первая из них - выбор языка. На момент написания статьи есть базовый - английский и переводы на русский, белорусский, украинский и турецкий языки. Кнопками навигации и/или энкодером можно выбрать нужное подменю и настроить необходимые параметры Параметров много, но не все они могут поддерживаться конкретным тюнером. Возможно, позднее я найду способ скрывать неактуальные параметры, а пока они просто есть, но ни на что не влияют в таком случае. Настройки дисплея. Можно задать яркость экрана в ждущем и рабочем режиме, а также развернуть экран на 180 градусов, если так удобнее для разработанной собственной платы. Для настройки кнопок пульта нужно просто активировать соответствующий кнопке пункт меню и нажать кнопку на ИК-пульте. Справа отобразится распознанный код кнопки В настоящий момент поддерживаются пульты, работающие по протоколам NEC, Samsung, RC5 и RC6 (протокол RC6 в железе не проверен ввиду отсутствия пульта, но код портировался из старого проекта, так что работать должно). В основном рабочем режиме при отсутствии каких-либо действие пользователя на экране отображается музыкальный спектр. Пока в настройках доступно немного параметров, как должен выглядеть этот основной экран, но что-нибудь интересное обязательно будет добавлено. Поскольку в проекте поддерживаются экраны разных разрешений, то для удобства отладки элементов, отображаемых на экране (размеры, координаты и т.п.) был создан своего рода эмулятор дисплея. Код написан на Qt/C++ и должен без проблем собираться не только под Linux. Желающие могут собрать свежую версию самостоятельно или воспользоваться приложенным к статье файлом. Для статьи я записал видеообзор основных возможностей проекта. Возможно, кому-то будет интересно посмотреть и другие связанные с проектом видеоролики. Ссылка на Youtube-плейлист. Как обычно, проект полностью открытый. Исходники проекта находятся на Github. В подкаталоге ./kicad можно найти имеющиеся на данный момент схемы/платы. В подкаталоге files - исходники шрифтов, иконок, эмулятора экрана и прочее. Для редактирования шрифтов и иконок удобно использовать программу lcd-image-converter, которую я утащил к себе в виде форка и добавил некоторые новые нужные функции, в частности - масштабирование шрифтов. Скачать сборку под Windows также можно у меня на Github. Актуальные прошивки всегда можно будет скачать в разделе релизов. Ввиду того, что проект ещё будет развиваться, настоятельно рекомендую научиться собирать прошивку из самых свежих исходников самостоятельно. В ссылке на Youtube-плейлист есть несколько видео, которые помогут разобраться, как это можно сделать. Тема на форуме, связанная с проектом, началась намного раньше этой статьи. Поэтому актуальную информацию имеет смысл начинать искать, начиная где-то с 20-й страницы. Но и предыдущие страницы прочесть будет небесполезно. Надеюсь, проект окажется интересным для всех. Удачного повторения.
Файлы: Все вопросы в Форум.
Эти статьи вам тоже могут пригодиться: |
|
|||||||||||||||
![]() |
![]() |


![]() |
![]() |
|||
|
||||
![]() |
![]() |