Olimexino-STM32. PWM синтезатор

Начав осваивать Olimexino-STM32, я попытался сходу что называется взять быка за рога, и снабдить будущий скетч командным интерпретатором. Но затея не удалась -- несмотря на то, что микроконтроллер STM32F103RB оснащён 128 Кб памяти Flash, памяти ОЗУ в нём всего 20 Кб, так что даже пустой скетч после компиляции претендует занять в памяти немногим больше 12 Кб. Когда командный интерпретатор уже научился вызывать команды с параметром и без, закончился стек, и программа стала зависать.

Скрепя сердце я стал читать, как использовать широтно-импульсную модуляцию (PWM), чтобы сделать простой синтезатор, подобный описанному на странице Arduino. Генератор сигналов. Начав программировать для Olimexino-STM32, я быстро столкнулся с тем, что после сброса и перезагрузки не инициализируются пользовательские переменные, так что их инициализацию следует проводить в функции setup().

int some_var1 = 12345; // Будет инициализирована только после холодного старта

void some_function()

{

static int some_var2 = 34567; // Аналогично

}

Правильно будет работать так:

int some_var1;

int some_var2;


void setup()

{

some_var1 = 12345;

some_var2 = 34567;

}

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

Синтезатор использует для вывода звука вместо внешнего цифро-аналогового преобразователя ЦАП (в микроконтроллере STM32F103RB встроенный ЦАП отсутствует), широтно-импульсную модуляцию (ШИМ) на двух выводах (стерео), максимальное значение таймера равно 2048 (11 бит), что даёт для частоты тактирования 72 МГц частоту сэмплирования 35.156 кГц. В качестве усилителя аудио-сигнала мною был использован Стереофонический усилитель для PWM-аудио микроконтроллера.

Для управления синтезатором в скетче используется микросхема-переходник USB-to-RS232 с платы Arduino, в качестве терминала использована программа screen:

screen /dev/ttyUSB0 57600

Общая схема подключения плат между собой выглядит следующим образом:

Управление синтезатором производится посредством ввода символов с клавиатуры в терминале. Структура управления синтезатором устроена следующим образом:

  • Символы 0..9 определяют длину ноты

  • Символы zsxdcvgbhnjm,l.;/ соответствуют полутонам октавы (z - до, s - до#, x - ре, и т.д., символ запятая - до следующей октавы и т.д.)

  • Символ = инициализирует синтезатор, выключая все звуки

  • Символ - переключает режим полифонии: полифонический/одноголосый

  • Символами q и w переключаются октавы

  • Символами r и t регулируется длина затухания (спад ноты)

Поскольку места для пользовательского кода в библиотеке Maple немного, то в ней предусмотрено при компиляции ограничение на максимальный размер кода скетча (17000 байт для скетчей, компилируемых в ОЗУ, и 108000 байт для скетчей, компилируемых во Flash). Поэтому удобно сперва выполнить компиляцию для загрузки скетча в ОЗУ (RAM), и только после того, как тот успешно загрузится и станет работать там, компилировать и загружать его уже во Flash.

Скачать код скетча PWMSynth.pde.

Автор: Андрей Шаройко <vanyamboe@gmail.com>