13.6.2. Музыкальный ящик

(Руководство разработчика по микроконтроллерам семейства HCS08)

Наш последний Пример 13.11 является комбинацией двух предыдущих устройств. Это музыкальный ящик, который изменяет проигрываемую мелодию на следующую, если обнаружит встряску по оси Y.

Алгоритм обнаружения встряски прост. Через интервалы в 50мс МК производит оцифровку канала Y датчика ускорения, Если он обнаружит код, отличный от кода 1g, и за ним последует код –1g, то следует менять мелодию.

Пример 13.11. Музыкальный ящик с датчиком перемещения

/*ДемонстрационнаяплатаDEMO9S08QE128,RTTTL-плеерсакселерометром
ПрограммаразработанаFabioPereira(01/20/08)
Joinville-SC-Brasil
www.sctec.com.br
Соединениянаплате:
PTA1-XOUT
PTA6-YOUT
PTA7-ZOUT
PTC4-MMA7260,входрежимаработыдатчика(0=спящий,1=активный)
PTD0-MMA7260,входвыборадиапазонаg-select1
PTD1-MMA7260,входвыборадиапазонаg-select2
PTB5-пьезоизлучатель(линияTPM1CH1)
ADC:
-триканаладляизмерениянапряженийпотремосям(PTA1,PTA6иPTA7)
TPM1:
-канал0:дляотсчетадлительностинотиорганизациимоментовоцифровкидатчика
-канал1:длягенерациичастотызвука
*/
#include/*forEnableInterruptsmacro*/
#include"derivative.h"/*includeperipheraldeclarations*/
#include"hcs08.h"/*Этонашфайлсобъявлениями*/
#defineACCEL_ONPTCD_PTCD4
//КоллекциямелодийвстандартеRTTL
constchar*rtttl_library[]=
{
{"U2Newyears:d=8,o=6,b=125:a5,a5,c,4a5,a5,a5,a5,c,c,e,4c,c,c,e,e,e,g,4e,e,e,a5,e,e,g,e,e,e,e,e,a5,a5,c,a5,a5,a5,a5,c,c,e,c,c,c,e,e,e,g,e,e,e,2a5"},
{"MissionImp:d=4,o=6,b=150:16d5,16d#5,16d5,16d#5,16d5,16d#5,16d5,16d5,16d#5,16e5,16f5,16f#5,16g5,8g5,4p,8g5,4p,8a#5,8p,8c6,8p,8g5,4p,8g5,4p,8f5,8p,8p,8g5,4p,4p,8a#5,8p,8c6,8p,8g5,4p,4p,8f5,8p,8f#5,8p,8a#5,8g5,1d5"},
{"ET:d=2,o=6,b=200:d,a,8g,8f#,8e,8f#,d,1a5,b5,b,8a,8g#,8f#,8g#,e,1c#7,e,d7,8c#7,8b,8a,8g,f,d.,16d,16c#,16d,16e,f,d,d7,1c#7"},
{"Batman:d=8,o=5,b=160:16a,16g#,16g,16f#,16f,16f#,16g,16g#,4a.,p,d,d,c#,c#,c,c,c#,c#,d,d,c#,c#,c,c,c#,c#,d,d,c#,c#,c,c,c#,c#,g6,p,4g6"},
{"Axelf:d=8,o=5,b=160:4f#,a.,f#,16f#,a#,f#,e,4f#,c6.,f#,16f#,d6,c#6,a,f#,c#6,f#6,16f#,e,16e,c#,g#,4f#."},
{"Hogans:d=16,o=6,b=45:f5.,g#5.,c#.,f.,f#,32g#,32f#.,32f.,8d#.,f#,32g#,32f#.,32f.,d#.,g#5.,c#,32c,32c#.,32a#5.,8g#5.,f5.,g#5.,c#.,f5.,32f#5.,a#5.,32f#5.,d#.,f#.,32f.,g#.,32f.,c#.,d#.,8c#."},
{"Jamesbond:d=4,o=5,b=320:c,8d,8d,d,2d,c,c,c,c,8d#,8d#,2d#,d,d,d,c,8d,8d,d,2d,c,c,c,c,8d#,8d#,d#,2d#,d,c#,c,c6,1b.,g,f,1g."},
{"Pinkpanther:d=16,o=5,b=160:8d#,8e,2p,8f#,8g,2p,8d#,8e,p,8f#,8g,p,8c6,8b,p,8d#,8e,p,8b,2a#,2p,a,g,e,d,2e"},
{"Countdown:d=4,o=5,b=125:p,8p,16b,16a,b,e,p,8p,16c6,16b,8c6,8b,a,p,8p,16c6,16b,c6,e,p,8p,16a,16g,8a,8g,8f#,8a,g.,16f#,16g,a.,16g,16a,8b,8a,8g,8f#,e,c6,2b.,16b,16c6,16b,16a,1b"},
{"Adamsfamily:d=4,o=5,b=160:8c,f,8a,f,8c,b4,2g,8f,e,8g,e,8e4,a4,2f,8c,f,8a,f,8c,b4,2g,8f,e,8c,d,8e,1f,8c,8d,8e,8f,1p,8d,8e,8f#,8g,1p,8d,8e,8f#,8g,p,8d,8e,8f#,8g,p,8c,8d,8e,8f"},
{"TheSimpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6"},
{"Indiana:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6"},
{"GirlFromIpanema:d=4,o=5,b=160:g.,8e,8e,d,g.,8e,e,8e,8d,g.,e,e,8d,g,8g,8e,e,8e,8d,f,d,d,8d,8c,e,c,c,8c,a#4,2c"},
{"TakeOnMe:d=4,o=4,b=160:8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5,8f#5,8e5,8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5"},
{"She:d=16,o=5,b=63:32b,4c6,c6,c6,8b,8d6,8c6.,8b,a,32b,2c6,p,c6,c6,b,8d6,8c6,8b,a,4c6.,8c6,b,32c6,4d6,8c6.,b,8a,8g,8f.,e,f,e,32f,2g,8p"},
{"Barbiegirl:d=4,o=5,b=125:8g#,8e,8g#,8c#6,a,p,8f#,8d#,8f#,8b,g#,8f#,8e,p,8e,8c#,f#,c#,p,8f#,8e,g#,f#"},
{"Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6"},
{"Xfiles:d=4,o=5,b=125:e,b,a,b,d6,2b.,1p,e,b,a,b,e6,2b.,1p,g6,f#6,e6,d6,e6,2b.,1p,g6,f#6,e6,d6,f#6,2b.,1p,e,b,a,b,d6,2b.,1p,e,b,a,b,e6,2b.,1p,e6,2b."},
{"Autumn:d=8,o=6,b=125:a,a,a,a#,4a,a,a#,a,a,a,a#,4a,a,a#,a,16g,16a,a#,a,g.,16p,a,a,a,a#,4a,a,a#,a,a,a,a#,4a,a,a#,a,16g,16a,a#,a,g."},
{"Spring:d=16,o=6,b=125:8e,8g#,8g#,8g#,f#,e,4b.,b,a,8g#,8g#,8g#,f#,e,4b.,b,a,8g#,a,b,8a,8g#,8f#,8d#,4b.,8e,8g#,8g#,8g#,f#,e,4b.,b,a,8g#,8g#,8g#,f#,e,4b.,b,a,8g#,a,b,8a,8g#,8f#,8d#,4b."},
};
//Этотмассивхранитчастотымузыкальныхнот
constunsignedintnote[4][12]=
{//CC#DD#EFF#GG#AA#B
262,277,294,311,330,349,370,392,415,440,466,494,//4-аяокт.
523,554,587,622,659,698,740,784,830,880,932,988,//5-аяокт.
1047,1109,1175,1244,1319,1397,1480,1568,1660,1760,1865,1976,//6-аяокт.
2093,2218,2349,2489,2637,2794,2960,3136,3320,3520,3728,3951//7-аяокт.
};
unsignedintchannel_reload_value,duration_timer;
unsignedcharaccel_timer;
charsound_playing=0;
charduration,octave;
unsignedinttempo;
unsignedinty_axis,y_avg;
charnext_song_flag=0;
unsignedintlast_y;
//ПодпрограммапрерыванияпопереполнениюTPM1:управляетдлительностьюзвучания
voidinterruptVectorNumber_Vtpm1ch0tpm1ch0_isr(void)
{
TPM1C0SC_CH0F=0;//СброситьфлагсобытияпереполненияCH0F
TPM1C0V+=4000;//Следующеесравнениечерез1мс
if(duration_timer)duration_timer--;//Декрементированиепеременнойtimer,
//еслиона>0
else//Еслипеременнаяtimer=0
{
TPM1C1SC=0;//ЗапретитьканалTPM1CH1(остановитьзвук)
sound_playing=0;//Сброситьфлагвоспроизведениязвука
}
if(accel_timer)accel_timer--;//Отсчетвременимеждумоментамиоцифровки
else
{
last_y=y_axis;//Оцифровкаосиy
accel_timer=50;//Следующаявыборкачерез50мс
}
}
//Подпрограммапрерыванияпособытиювканалевыходногосравнения1модуляTPM1:
//управляетгенерациейчастотыналинии
//Состояниелинииинвертируетсяприкаждомсобытиивыходногосравнения
voidinterruptVectorNumber_Vtpm1ch1tpm1ch1_compare(void)
{
TPM1C1SC_CH1F=0;//Сброситьфлагсобытиявканале
TPM1C1V+=channel_reload_value;//Задатьновоезначениедлясравнения
}
//ФункциягенерациизвуканалинииPTB5(TPM1CH1):частотавГц,длительностьвмс
voidsound(unsignedintfreq,unsignedintdur)
{
while(sound_playing);//Еслизвукпроигрывается,тождатьдоегозавершения
//Значениедляперезагрузкиканала=½периодачастотысигнала
channel_reload_value=(4000000/freq)/2;
duration_timer=dur;//Установитьвремязвучания
//Назначитьрежиминвертированиясигналадляканала1
TPM1C1V=channel_reload_value;//Установить1-оезначениесравнения
TPM1C1SC=bCHIE|TPM_COMPARE_TOGGLE;
sound_playing=1;//Звукпроигрыватьдосбросафлага
}
//Функциягенерациимелодии,записаннойвформатеRTTTL
voidplay_song(char*song)
{
unsignedchartemp_duration,temp_octave,current_note,dot_flag;
unsignedintcalc_duration;
duration=4;//Длительностьзвучания=4/4=1
tempo=63;//Темп=63bpm
octave=6;//Октава=6-я
while(*song!=':')song++;//Найтипервыйсимвол':'
song++;//Пропуститьсимвол':'
while(*song!=':')//Повторятьдосимвола':'
{
if(*song=='d')//Еслиэтосимволдлительностиноты,то
{
duration=0;//временноduration=0
song++;//Перейтикследующемусимволу
while(*song=='=')song++;//Символ'='пропустить
while(*song=='')song++;//Пробелыпропустить
//Еслисимвол–число,тозаписатьеговпеременнуюduration
if(*song≥'0'&&*song≤'9')duration=*song-'0';
song++;//Перейтикследующемусимволу
//Еслисимвол–тожечисло(длительностьможетсостоятьиздвухцифр),то
if(*song≥'0'&&*song≤'9')
{//умножитьна10идобавитьтекущуюцифру(символ)
duration=duration*10+(*song-'0');
song++;//Перейтикследующемусимволу
}
while(*song==',')song++;//Пропуститьсимвол','
}

if(*song=='o')//Еслиэтоуказательоктавы,то
{
octave=0;//временноoctave=0
song++;//Перейтикследующемусимволу
while(*song=='=')song++;//Пропуститьсимвол'='
while(*song=='')song++;//Пропуститьпробелы
//Еслисимвол–число,тозаписатьеговпеременнуюoctave
if(*song≥'0'&&*song≤'9')octave=*song-'0';
song++;//Перейтикследующемусимволу
while(*song==',')song++;//Пропуститьсимвол','
}
if(*song=='b')//Еслиэтоуказательтемпа(нотвминуту),
{
tempo=0;//временноtempo=0
song++;//Перейтикследующемусимволу
while(*song=='=')song++;//Пропуститьсимвол'='
while(*song=='')song++;//Пропуститьпробелы
//Теперьчитатьцифрытемпа(можетбытьчислоиз3цифр)
if(*song≥'0'&&*song≤'9')tempo=*song-'0';
song++;//Перейтикследующемусимволу
if(*song≥'0'&&*song≤'9')
{
tempo=tempo*10+(*song-'0');//Числосостоитиз2цифр
song++;//Перейтикследующемусимволу
if(*song≥'0'&&*song≤'9')
{
tempo=tempo*10+(*song-'0');//Числосостоитиз3цифр
song++;//Перейтикследующемусимволу
}
}
while(*song==',')song++;//Пропуститьсимвол','
}
while(*song==',')song++;//Пропуститьсимвол','
}
song++;//Перейтикследующемусимволу
//readthemusicalnotes
while(*song)//Повторять,покасимволынепустые
{
current_note=255;//Текущаянота-пауза
temp_octave=octave;//Установитьоктавупоумолчанию
temp_duration=duration;//Установитьдлительностьпоумолчанию
dot_flag=0;//Сброситьфлагdotflag
//Определитьиобработатьпрефиксдлительности
if(*song≥'0'&&*song≤'9')
{
temp_duration=*song-'0';
song++;
if(*song≥'0'&&*song≤'9')
{
temp_duration=temp_duration*10+(*song-'0');
song++;
}
}
//Определитьноту
switch(*song)
{
case'c':current_note=0;break;//C(до)
case'd':current_note=2;break;//D(ре)
case'e':current_note=4;break;//E(ми)
case'f':current_note=5;break;//F(фа)
case'g':current_note=7;break;//G(соль)
case'a':current_note=9;break;//A(ля)
case'b':current_note=11;break;//B(си)
case'p':current_note=255;break;//пауза
}
song++;//Перейтикследующемусимволу
//Еслизасимволомнотыследуетсимвол#,
if(*song=='#')
{
current_note++;//тоувеличитьна1переменнуюnote
//(A→A#,C→C#,D→D#,F→F#,G→G#)
song++;//Перейтикследующемусимволу
}
//Еслиследующийсимвол'.'(признакувеличениядлительностинотына50%),
if(*song=='.')
{
dot_flag=1;//тоустановитьфлагdotflag
song++;//Перейтикследующемусимволу
}
//Анализироватьпризнакоктавы
if(*song≥'0'&&*song≤'9')
{
temp_octave=*song-'0';//Установитьоктаву
song++;//Перейтикследующемусимволу
}
if(*song=='.')//Запризнакомоктавыдолжнаследоватьточка
{
dot_flag=1;//Еслиэтотак,тоустановитьфлагdotflag
song++;//Перейтикследующемусимволу
}
while(*song==',')song++;//Пропуститьсимвол','
//Рассчитатьдлительностьноты
calc_duration=(60000/tempo)/(temp_duration);
calc_duration*=4;//Нотасостоитиз4интерваловтемпа
//Еслифлагdotflagустановлен,тоувеличитьдлительностьна50%
if(dot_flag)calc_duration=(calc_duration*3)/2;
//Еслитекущаянота–непауза,топроигрыватьэтунотусиспользованием
//функцииsound
if(current_note<255)sound(note[temp_octave-4][current_note],calc_duration);
else
{//Еслитекущаянота=255(пауза),тореализоватьзадержку
duration_timer=calc_duration;
sound_playing=1;
}
while(sound_playing);//Ожидать,покатекущаянотаилипаузанезакончится
if(next_song_flag)break;//Еслиобнаруженоперемещениеплатыотладки,то
//перейтикследующеймелодии
}
}
//ПодпрограммапрерыванияотмодуляADC
voidinterruptVectorNumber_Vadcadc_isr(void)
{
y_avg=(y_avg+ADCR)-y_axis;//Сумма8последнихизмеренийпоосиy
y_axis=y_avg>>3;//РасчетскользящегосреднегоосиY
//Еслиобнаруженопоследнееизмерениекоординатыпоyв+,апредыдущеев-,то
//установитьфлагдлявоспроизводствановоймелодии
//Ксловиепереходакследующеймелодии
if(y_axis<800&&last_y>3000)next_song_flag=1;
}
voidmain(void)
{
unsignedcharsong_sel;
SOPT1=bBKGDPE;//Разрешитьфункциюлинииотладки
ICSSC=DCO_MID|NVFTRIM;//КопироватьбитFTRIM,выбратьверхнийдиапазонDCO
ICSTRM=NVICSTRM;//КопироватьподстроечноечислоTRIM
ICSC1=ICS_FLL|bIREFS;//ВыбратьрежимFEI(ICSOUT=DCOOUT=1024*IRCLK)
ICSC2=BDIV_1;//ICSOUT=DCOOUT/1
//BUSCLK=16МГц
TPM1SC=TPM_BUSCLK|TPM_DIV4;//TPMCK=4МГц
//Установитьрежимсравнениядляканала0(толькодляпрерывания),интервал-1мс
TPM1C0V=3999;
TPM1C0SC=bCHIE|TPM_COMPARE_INT;
/*ИнициализациямодуляADC:низкаяскоростьпреобразования,разрешающая
способность12бит,ADICLK=00000011,ADCK=BUSCLK/8*/
//СкоростьвыборкиADCсоставляет25000выбороквсекунду
ADCCFG=bADLSMP|ADC_12BITS|ADC_INTCLK|ADIV_8;
APCTL2=ADPC8;//ЛинияADP8врежимевходаАЦП
//ИнициализацияAD:канал8,разрешитьпрерыванияотмодуляADC,
//режиммногократногопреобразования
ADCSC1=bAIEN|ADCH8|bADCO;
PTDD=0;//Назначитьдиапазонпреобразованияв1.5g
PTDDD=BIT_0|BIT_1;//ЛинииPTD0иPTD1–навывод
PTBDS=BIT_5;//Включитьповышеннуюнагрузочнуюспособность
//дляPTB5(звукоизлучатель)
PTCDD=BIT_4;//ЛинияPTC4–навывод
y_avg=0;
y_axis=0;
accel_timer=50;//Установитьинтервалмеждумоментамиоцифровки
ACCEL_ON=1;//Акселерометрвактивныйрежим
EnableInterrupts;//Разрешитьпрерывания(CCR:I=0)
while(1)
{
for(song_sel=0;song_sel<20;song_sel++)
{
duration_timer=250;
sound_playing=1;
while(sound_playing);//Ожидать250мсдоначаласледующеймелодии
play_song(rtttl_library[song_sel]);//Воспроизведениемелодии

//Ожидать2спередначаломследующеймелодии
duration_timer=2000;//2с=2000мс
sound_playing=1;
//Перейтикследующеймелодии,если2сзавершилисьилимелодияпропускается
while(sound_playing&&!next_song_flag);
next_song_flag=0;
}
}
}


Электронные компоненты Freescale >>>
Подробнее о компании Freescale >>>