RTTL – це популярний формат для запису рингтонів мобільних телефонів, створений компанією Nokia. Рінгтон записується як текстовий файл за допомогою кодів, які вказують ноти і їх тривалість. Будь-який файл у форматі RTTL містить назву рингтон, тривалість (d), октаву (о), ритм (Ь) і самі ноти. Ця інформація декодується при відтворенні рингтон. У даному проекті програвач рингтонів реалізований на мікроконтролері Tiny861. Динамік підключений до потужного звуковому підсилювача TDA2020. Блок- схема програвача показана на рис. 6.9.

Рис. 6.9. Блок-схема програвача рингтонів

Специфікація проекту

Мета проекту-створити декодер і програвач RTTL на основі мікроконтролера AVR. Формат RTTL був обраний тому, що в Інтернеті є велика кількість рингтонів, які можна скачати, записати в пам’ять мікроконтролера і відтворювати за допомогою такого програвача.

Опис проекту

Апаратна частина проекту точно така ж, що і в проекті будильника для школярів (див. Проект 19 з глави 4).

Принципова схема пристрою зображена на рис. 6.10. У пристрої необхідний DIP-перемикач, який обиратиме мелодію з наявних у пам’яті мікроконтролера. Принципова схема відповідної ланцюга наведена на рис. 6.11. DIP-перемикачі (їх зображено чотири, але використовуються тільки три) дозволяють користувачеві вибрати один з восьми рингтонів, що зберігаються в пам’яті програм мікроконтролера. Для запуску відтворення вибраного рингтон необхідно натиснути кнопку S1.

Рис. 6.10. Принципова схема програвача рингтонів

Рис. 6.11. Принципова схема DIP-перемикачів для програвача рингтонів

Конструкція

Компонування плати в програмі EAGLE (і принципову схему) можна завантажити за посиланням: www.avrgemus.com/tinyavrl.

Друкована плата однобічна (на стороні компонентів є всього декілька перемичок). Обидві сторони плати показані на рис. 6.12 і 6.13.

Програмування

Відкомпільований вихідний код проекту (разом з файлом MAKEFILE) можна завантажити за посиланням: www.avrgenius.com/tinyavrl.

Тактова частота дорівнює 8 МГц. Контролер запрограмований за допомогою STK500 в режимі програмування ISP. Найважливіші фрагменти коду наведені в лістингах 6.9-6.12. Як уже згадувалося, формат RTTL- це текстовий файл з інформацією про характеристики пісні. У лістингу 6.7 приведена проста мелодія у форматі RTTL. На початку коду вказана наступна інформація: назва пісні, потім тривалість за замовчуванням (D), октава (о), ритм (ь). Після цього йде інформація про всі нотах.

Happy Birthday Song: d=4, o=5, b=12 5: 8g.,

Хбд ^ д.сб, 2b, 8g., 16g, a, g, d6,2c6,

8g. ,16g/g6/e6/c6/b/a/8f6. ,16f6,e6, c6/d6/2c6/ 8g., 16g, a, g, c6,2b, 8g., 16g, a, g, d6,2c6,8g., Хбд ^ б ^ б ^ б ^ а,

8f6.,16f6,e6,c6,d6,2c6

Пісні зберігаються в Flash-пам’яті мікроконтролера за допомогою макросу

PROGMEM (Лістинг 6.8).

char songl [] PROGMEM = “Happy Birthday Song: d = 4, o = 5, b = 125: 8g., 16g, a, g, сб,

2b, 8g., 16g, a, g, d6,2c6,8g., 16g, g6, e6, сб, b, a, 8f6., 16f6, еб, сб, d6,2c6,8g.,

16g,a,g,c6,2b,8g.,16g,a,g,d6,2c6,

8g., 16g, g6, e6, c6, b, a, 8f6., 16f6, e6, сб, d6,2c6 “;

Наше перше завдання – розшифрувати цю мову і отримати потрібну інформацію про кожній ноті (т. Е. Її тривалість і швидкість відтворення). Частоти нот зберігаються в масиві top []. У лістингу 6.9 приведений код, який декодує цей формат у відповідності зі специфікаціями RTTL.

// Формат: d = N, o = N, b = NNN:

// Знайти начало (пропустити назву тощо) while (pgm_read_byte (р)! = ‘:’)

р ++; // Пропустити ‘:’

р ++; // Перейти до ‘d’

// Отримати тривалість за замовчуванням if (pgm_read_by t е (p) == ‘d’)

{

p ++; // Пропустити “d”

p ++; // Пропустити “=”

num = 0;

while (isdigit (pgm_read_byte (p)))

{

num = (num * 10) + (pgm_read__byte (p++) – ‘ O’);

}

if (num > 0)

default_dur = num; p ++; // Пропустити двокрапка

}

// Отримати октаву за замовчуванням if (pgm_read_byte (p) == ‘o’)

{

p ++; // Пропустити “про

р ++; // Пропустити “=”

num = pgm_read_byte(p++) –    10′;

if (num >= 4 ScSc num <=8)

default_oct = num;

p ++; // Пропустити двокрапка

}

// Отримати значення ВРМ if (pgm_read__byte (р) == ‘b’)

{

р ++; // Пропустити “b =”

р ++; // Пропустити Hb="

num = 0;

while (isdigit (pgm_read_byte (p)))

{

num = (num * 10) + (pgm_read_byte (p++) – * 0′);

}

bpm = num;

p ++; // Пропустити двокрапка

}

// BPM – це число четвертної нот в хвилині wholenote = (((60.0 * 1000.0) / (float) bpm) * 4.0);

// Цей час повної ноти (в мілісекундах)

// Початок циклу ноти whi1е (pgm_read_bytе (р))

{

// Спочатку отримати тривалість ноти (якщо вона є) num = 0;

while (isdigit (pgm_read__byte (p) ))

{

num = (num * 10) + (pgm_read__byte (p++) – ‘0’);

}

if (num)

duration = wholenote / (float) num; // Мілісекунди відтворення ноти else

duration = wholenote / (float)default_jdur;

// Нам потрібно буде перевірити, чи не подовжена Чи це була нота // тепер отримаємо ноту note = 0;

switch (pgm_read_byte (р))

{

case ‘з’: note = 1;

break; case 1d’: note = 3; break; case ‘e’: note = 5; break; case ‘f’: note = 6; break; case ‘g’: note = 8; break; case ‘a’: note = 10; break; case ‘b’: note = 12; break;

case 1p’: note = 0;

}

p++;

// Тепер потрібно порахувати можливий дієз ‘#’ if (pgm_read_byte (р) == ‘#’)

{

note++;

р ++;

}

octave = top[note];

// Тепер потрібно порахувати можливу подовжену ноту if (pgm_read_byte (р) ==

{

duration += duration/2;

Р ++;

}

// Тепер отримаємо тональність if (isdigit (pgm_read_byte (р)))

{

scale = pgm_read_byte(p) – ‘O’;

P++;

}

else

{

scale = default_oct;

}

/ * Обробити октаву * / switch (scale)

{

case 4: / * Нічого не робимо * / // x »y = x / 2 * y break;

case 5 : /* %2 */ octave = octave » 1; break;

case 6 : /* %4 */ octave = octave » 2; break;

case 7 : /* %8 */ octave = octave » 4; break;

case 8 : /* %16 */ octave =4 octave » 8; break;

}

if(pgm_read_byte(p) == ‘ , ‘)

p ++; // Пропустити кому перед наступною нотою (або ми вже в кінці)

Після того як ми отримали тональність і тривалість ноти – ми відтворюємо її протягом зазначеної тривалості. Це робиться за допомогою двох таймерів: TimerO задає тривалість ноти (в режимі переповнення), Timerl (в режимі ШІМ) виробляє меандр потрібної частоти за допомогою установки значення тор в регістрі ocric (лістинг 6.10).

DDRB | = (1 «РВЗ); // Налаштування вихідного контакту каналу ШІМ

TCCR0A & = ~ (1 «WGM00); // Режим Normal

TCCROB | = ((1 «CS02) I (1« CS00)); // Попередній дільник 1024 if (note) // Якщо це нота (

TCCRlA | = ((1 «СОМ1В1) | (1« PWM1B)); // Неінвертуючий режим, швидка ШІМ TCCR1B | = ((1 «CS13) | (1« CS10)); // Попередній дільник 256 TCCR1C | = (1 «СОМ1В1); // Очистити при збігу

TCCR1D &=~ ( (1«WGM11)   |      (1«WGM10) ) ;

0CR1C = octave; // Настройка значення Top

OCR1B = (0CR1C »1); // Середнє значення 50%

TCNTOL = 0; for (;;)

{

if (TCNTOL> = 78) // перевірка тривалості

{

duration = duration – 10.0;

TCNTOL = 0;

}

if(duration <= 0.00) break;

}

TCCR0B = 0x00;

}

else // Якщо трапляється пауза

{

TCNTOL = 0; for (;;)

{

if (TCNTOL> = 78) // Перевірка тривалості

{

duration = duration – 10.0;

TCNTOL = 0;

}

if(duration <= 0.00) break;

}

TCCR0B = 0x00;

}

Робота пристрою

В пам’ять програм мікроконтролера завантажено вісім пісень у форматі RTTL. Виберіть певну мелодію за допомогою DIP-перемикачів і натисніть кнопку S1. Пристрій почне відтворювати пісню. Закінчивши відтворення, система зупиняється. Для відтворення іншої пісні (або для повтору тієї ж самої) потрібно знову натиснути кнопку S1.

Джерело: Гадре, Д., Цікаві проекти на базі мікроконтролерів tinyAVR / Дхананья Гадре, Нігула Мелхотра: Пер. з англ. – СПб .: БХВ-Петербург, 2012. – 352 с .: іл. – (Електроніка)