Введение
Написал программный модуль, позволяющий добавить функцию воспроизведения мелодий или последовательностей звуков практически в любой проект на микроконтроллере AVR.
Особенности модуля:
- простая интеграция с готовым проектом
- задействован только 8-ми разрядный таймер т2, при этом остается возможность использовать его для опроса или формирования временных интервалов
- модуль настраивается практически на любую частоту тактового генератора
- высота нот задается в виде символических констант (С0, А2 и т.д) или в Герцах
- длительности задаются в стандартном виде (четверти, восьмые и т.д.) или в миллисекундах
- имеется возможность задавать темп воспроизведения мелодии и количество ее повторений
- в процессе воспроизведения мелодия может быть поставлена на паузу
Подключение звукового модуля
1. Переписываем все файлы модуля (tone.h, sound.h, sound.c) в папку проекта.
2. Подключаем файл sound.c к проекту.
Для IAR `a – кликнуть правой кнопкой мышке в окне workspace и выбрать Add > Add Files…
Для WINAVR примерно то же самое, только sound.c нужно еще прописать в make файл:
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c sound.c
3. Включаем заголовочный файл sound.h в соответствующий модуль. Например, в main.c
#include "sound.h"
4. Задаем настройки модуля в файле sound.h
//если закомментировать - длительность нот будет
//рассчитываться из BPM`а заданного в мелодии
//если оставить, то из значения заданного ниже
//#define SOUND_BPM 24
//тактовая частота мк
#define SOUND_F_CPU 16U
//вывод микроконтроллера, на котором будет генерироваться звук
#define PORT_SOUND PORTB
#define PINX_SOUND 0
//количество заданных мелодий.
#define SOUND_AMOUNT_MELODY 4
5. Добавляем в sound.c свои мелодии и прописываем названия мелодий в массив melody[].
Добавление мелодий
Мелодия представляет собой массив 16-ти разрядных чисел и имеет следующую структуру
BPM (количество четвертных нот в минуту) – это константа, используемая для расчета длительности нот и определяющая скорость воспроизведения мелодии.
BPM может принимать значения от 1 до 24, что соответствует 10 и 240 четвертным нотам в минуту соответственно.
Если длительность нот/звуков задается в миллисекундах, то BPM, прописанный в массиве, должен быть равен 1.
Если в заголовочном файле sound.h константа SOUND_BPM закомментирована, то длительность нот рассчитывается в процессе выполнения программы по BPM `у заданному в массиве. Если SOUND_BPM не закомментирована – длительность нот рассчитывается еще на этапе компиляции, исходя из значения этой константы, при этом все мелодии будут воспроизводиться в одинаковом темпе. Это ограничивает функционал, но позволяет сэкономить несколько байт кода.
Количество повторений. Может принимать значения 1 ... 254 и LOOP (255). LOOP - означает, что мелодия будет повторяться бесконечно, пока не будет подана команда SOUND_STOP или SOUND_PAUSE.
Длительность ноты – время в течение, которого генерируется заданный тон звука или выдерживается пауза. Может задаваться в ms, с помощью макроса ms(x), или в виде стандартных длительностей нот – восьмых, шестнадцатых и т.д. Ниже приведен список поддерживаемых длительностей. Если возникнет нужда в каких-то экзотических длительностях, их всегда можно добавить в файле tone.h
n1 - целая нота
n2 - половинная нота
n4 - четверть
n8 - восьмая
n3 - восьмая триоль
n16 - шестнадцатая
n6 - секстоль
n32 - тридцать вторая
Высота ноты задается с помощью символических констант описанных в файле tone.h, например C2, A1 и т.д. Также высота нот может задаваться в Герцах с помощью макроса f(x).
В программе есть ограничения на минимальную и максимальную частоту звука!
Маркер конца мелодии. Значение последнего элемента массива обязательно должно быть нулевым.
Использование звукового модуля
В начале main`a нужно обязательно вызывать функцию SOUND_Init(). Эта функция настраивает вывод микроконтроллера на выход, конфигурирует таймер Т2 и инициализирует переменные модуля.
Затем нужно установить флаг разрешения прерываний - __enable_interrupt(), ведь в модуле используется прерывания таймера Т2 по переполнению и совпадению.
После этого можно запускать воспроизведение мелодий.
Например, так:
SOUND_SetSong(2); //установить указатель на 2-ю мелодию
SOUND_Com(SOUND_PLAY); //воспроизвести мелодию
Или так:
//установить указатель на 2-ю мелодию
//и запустить воспроизведение
SOUND_PlaySong(2);
Воспроизведение мелодии можно в любой момент остановить, подав команду SOUND_STOP.
Также мелодию можно поставить на паузу с помощью команды SOUND_PAUSE. Последующая подача команды SOUND_PLAY возобновляет воспроизведение мелодии с места, на котором произошла остановка.
В принципе данный функционал не особо нужен (это уж я просто навернул) и при работе с модулем достаточно функции SOUND_PlaySong(unsigned char numSong);
Файлы
Примеры использования звукового модуля вы можете скачать по ссылкам ниже. Схему рисовать не стал, потому что там все просто.
Пьезоизлучатель подключен к выводу PB0, кнопка запуска мелодий подключена к выводу PD3. В проектах определено 4 мелодии. Нажатие на кнопку запускает каждый раз новую мелодию. Используется микроконтроллер atmega8535. Изначально хотел заморочиться на проект с четырьмя кнопками - PLAY, STOP, PAUSE и NEXT, но потом подумал, что это лишнее.