チーム2045
課題名
国歌のカラオケを作る
研究者名
iyama takumi
yuto iwashima
概要
国歌をスピーカーで演奏し、それに沿ってLCDに歌詞を表示する。
タイマーを設置し、任意のタイミングで割り込みを行うことで演奏を行う。
国歌のテンポは定まっていないが、慣習的にだいたい「♪=60」程であることが調べて判明したので、それに合わせることにした。
「♪=60」とは一分間に四分音符が60個入るテンポである。つまり、1秒に1回四分音符が入るテンポである。
国歌はほとんどが四分音符、まれに八分音符(四分音符の半分の音の長さ)で構成されている。音の長さの短い八分音符のテンポに合わせて割り込みのタイマーを作れば、どちらの音符も任意のタイミングで演奏できる。1秒に1回四分音符が入るテンポ、つまり1秒に2回八分音符が入るテンポでタイマーを作成する。
(参考にさせていただいた譜面 http://www.plamrec.com/kimigayo-bansou.htm)
(参考にさせていただいた課題 チーム1512「みんなで覚えて歌おう校歌!」、timer_pwm)
使用器具
PSoC基盤 1個
MiniProg 1個
ジャンパ線 2本(スピーカーと接着されている)
スピーカー 1個
ソースコード
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#pragma interrupt_handler myISR
int PW=125;
int SILENT=0, D=229, L=204, M=182, F=172, S=153, R=136, C=121, DD=115, LL=102;
int TC=0;
void myISR(void)
{
TC += 1; PWM16_1_WritePulseWidth(PW); //0小節 if(TC == 1){ PWM16_1_WritePeriod(L); LCD_1_Position(0,0); LCD_1_PrCString("kimigayowa");}
else if(TC == 3) PWM16_1_WritePeriod(D);
else if(TC == 5) PWM16_1_WritePeriod(L);
else if(TC == 7) PWM16_1_WritePeriod(M); else if(TC == 9) PWM16_1_WritePeriod(S); else if(TC == 11) PWM16_1_WritePeriod(M); else if(TC == 13) PWM16_1_WritePeriod(L); else if(TC == 17){ PWM16_1_WritePeriod(M); LCD_1_Position(0,0); LCD_1_PrCString("tiyoniyatiyoni");} else if(TC == 19) PWM16_1_WritePeriod(S);
else if(TC == 21) PWM16_1_WritePeriod(R);
else if(TC == 23) PWM16_1_WritePeriod(S); else if(TC == 24) PWM16_1_WritePeriod(R);
else if(TC == 25) PWM16_1_WritePeriod(LL); else if(TC == 27) PWM16_1_WritePeriod(C); else if(TC == 29) PWM16_1_WritePeriod(R);
else if(TC == 31) PWM16_1_WritePeriod(S); else if(TC == 33){ PWM16_1_WritePeriod(M); LCD_1_Position(0,0); LCD_1_PrCString("sazareishino ");} else if(TC == 35) PWM16_1_WritePeriod(S); else if(TC == 37) PWM16_1_WritePeriod(R); else if(TC == 41) PWM16_1_WritePeriod(LL); else if(TC == 43) PWM16_1_WritePeriod(DD); else if(TC == 45) PWM16_1_WritePeriod(LL);
else if(TC == 49){ PWM16_1_WritePeriod(M); LCD_1_Position(0,0); LCD_1_PrCString("iwaotonarite ");} else if(TC == 51) PWM16_1_WritePeriod(S); else if(TC == 53) PWM16_1_WritePeriod(R); else if(TC == 55) PWM16_1_WritePeriod(S); else if(TC == 57) PWM16_1_WritePeriod(M); else if(TC == 60) PWM16_1_WritePeriod(S); else if(TC == 61) PWM16_1_WritePeriod(L); else if(TC == 65){ PWM16_1_WritePeriod(R); LCD_1_Position(0,0); LCD_1_PrCString("kokenomusumade ");}
else if(TC == 67) PWM16_1_WritePeriod(DD); else if(TC == 69) PWM16_1_WritePeriod(LL); else if(TC == 73) PWM16_1_WritePeriod(DD); else if(TC == 75) PWM16_1_WritePeriod(LL);
else if(TC == 77) PWM16_1_WritePeriod(R); else if(TC == 79) PWM16_1_WritePeriod(S); else if(TC == 81) PWM16_1_WritePeriod(R); else if(TC == 83) PWM16_1_WritePeriod(S); else if(TC == 84) PWM16_1_WritePeriod(M); else if(TC == 85) PWM16_1_WritePeriod(L); else if(TC == 87){ PWM16_1_WritePeriod(SILENT); LCD_1_Position(0,0); LCD_1_PrCString("end ");}
}
void main(void)
{
M8C_EnableGInt;
PWM16_1_Start();
Timer16_1_EnableInt();
Timer16_1_Start();
LCD_1_Start();
while(1)
{};
// M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts // Insert your main routine code here.
}
考察
timerの設定について
初期値は「クロック:60KHz」「Period:10000」で、1/6秒ごとに割り込みが入るようになっている。
上記の「概要」より、八分音符を1秒に2回入れたい、つまり、割り込みを1/2秒ごとに起こしたい。
よって設定は「クロック:60KHz」「Period:30000」とした。こうすれば1/2秒ごとに割り込みが起きるようになり、八分音符のある譜面でも「♪=60」のテンポをきれいに演奏できることになる。
今回はテンポ60で4分音符と8分音符を使って演奏したが、タイマーの周期を変更すればより速いテンポでの演奏や16分音符への対応も容易である。
スピーカーが二つ以上あれば同時多重演奏ができるのではないかと考えたが、今回はスピーカーが一つしかなかったため試すことが出来なかった。多重演奏が可能であれば、再現できる曲の幅が広がるはずである。
- 最終更新:2020-10-20 14:31:51