H8-3048でネイティブフェイス鳴らしてみた


 H8マイコンを使い始めて勉強中に思いついた一品
 0と1を交互に出力したら音鳴るんじゃね?と唐突に思ったことから全てが始まった
 使用ボードは、AKI-H8/3048

 全力で0,1繰り返しても周波数的に人間には聞こえない領域なので適当に待ち時間を入れる。

 大体こんな感じだったかな?多分
void main(){
 int a;
 PA.DDR = 0xff;
 while(1){
  a=1000;
  while(a--);
  PA.DR.BIT1 = 1;
  
  a=1000;
  while(a--);
  PA.DR.BIT1 = 0;
 }
}

 で、それで音が鳴るのがわかってんで
 タイマー使って音の高さのテストのソースが以下
void main(){
#include <3052.h>

int a;
int i;

void wait(){
 a = 30000;
 while(a--);
}

int main(){
 PA.DDR = 0xff;
 ITU0.TCR.BYTE = 0x23; //GRBコンペアマッチ、TCNTクリア、クロック1/8
 ITU.TMDR.BIT.PWM0 = 1;
 ITU0.GRB = 2000; //GRBの半分
 ITU0.GRA = 4000;

 ITU.TSTR.BIT.STR0 = 1; //ITU0スタート
 
 
 while(1){
  ITU0.GRA = 4000;
  ITU0.GRB = 2000; wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();
  ITU0.GRB = 1500; wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();
  ITU0.GRB = 1000; wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();
  ITU0.GRB = 500; wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();
  ITU0.GRB = 100; wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();
  ITU0.GRB = 1; wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();wait();
 }
}

 当時のソースのままなので、色々突っ込み所満載w
 
 そのごスイッチ8個で鍵盤っぽいのを作ってみた
void main(){

#include <3048.h>

//全音符の長さ 後のbpm
#define ZENONP 7000
//ノーマルは7000?

void sound(int onkai1,int onkai2,int onkai3,int onkai4,int onkai5){
 ITU0.GRA = onkai1/2; //GRBの半分
 ITU0.GRB = onkai1;
 
 ITU1.GRA = onkai2/2; //GRBの半分
 ITU1.GRB = onkai2;
 
 ITU2.GRA = onkai3;
 ITU2.GRB = onkai3/2; //GRAの半分
 
 ITU3.GRA = onkai4/2; //GRBの半分
 ITU3.GRB = onkai4;
 
 ITU4.GRA = onkai5/2; //GRBの半分
 ITU4.GRB = onkai5;
}

int a;
int i;

void wait(int t){
 for(i=1; i< 128/t ; i++){
  a = ZENONP;
  while(a--);
 }
}

int main(){
 PA.DDR = 0xff;
 PB.DDR = 0xff;
 
 ITU0.TCR.BYTE = 0x43; //GRBコンペアマッチ、TCNTクリア、クロック1/8
 ITU0.TIOR.BIT.IOA = 3; //GRAのコンペアマッチでTIOCA0にトグル出力、カウンタクリア
 ITU0.GRA = 4545/2; //GRBの半分
 ITU0.GRB = 4545;
 
 ITU1.TCR.BYTE = 0x43; //GRBコンペアマッチ、TCNTクリア、クロック1/8
 ITU1.TIOR.BIT.IOA = 3; //GRAのコンペアマッチでTIOCA1にトグル出力、カウンタクリア
 ITU1.GRA = 4545/2; //GRBの半分
 ITU1.GRB = 4545;
 
 // ※ITU2にはトグル出力の機能がないのでPWMを使用
 ITU2.TCR.BYTE = 0x23; //GRAコンペアマッチ、TCNTクリア、クロック1/8
 ITU.TMDR.BIT.PWM2 = 1; //チャンネル2 PWMモード
 ITU2.GRA = 4545;
 ITU2.GRB = 4545/2; //GRAの半分
 
 ITU3.TCR.BYTE = 0x43; //GRBコンペアマッチ、TCNTクリア、クロック1/8
 ITU3.TIOR.BIT.IOA = 3; //GRAのコンペアマッチでTIOCA3にトグル出力、カウンタクリア
 ITU3.GRA = 4545/2; //GRBの半分
 ITU3.GRB = 4545;
 
 ITU4.TCR.BYTE = 0x43; //GRBコンペアマッチ、TCNTクリア、クロック1/8
 ITU4.TIOR.BIT.IOA = 3; //GRAのコンペアマッチでTIOCA4にトグル出力、カウンタクリア
 ITU4.GRA = 4545/2; //GRBの半分
 ITU4.GRB = 4545;
 
 
 ITU.TSTR.BIT.STR0 = 1; //ITU0スタート
 ITU.TSTR.BIT.STR1 = 1; //ITU1スタート
 ITU.TSTR.BIT.STR2 = 1; //ITU2スタート
 ITU.TSTR.BIT.STR3 = 1; //ITU3スタート
 ITU.TSTR.BIT.STR4 = 1; //ITU4スタート
 
 #include "def.h"
 
 while(1){
  wait(64);
  
  if(P7.DR.BIT.B0){
   sound(DO5,___,___,___,___);
  }
  else if(P7.DR.BIT.B1){
   sound(RE5,___,___,___,___);
  }
  
  else if(P7.DR.BIT.B2){
   sound(MI5,___,___,___,___);
  }
  else if(P7.DR.BIT.B3){
   sound(FA5,___,___,___,___);
  }
  
  else if(P7.DR.BIT.B4){
   sound(SO5,___,___,___,___);
  }
  else if(P7.DR.BIT.B5){
   sound(RA5,___,___,___,___);
  }
  
  else if(P7.DR.BIT.B6){
   sound(SI5,___,___,___,___);
  }
  else if(P7.DR.BIT.B7){
   sound(DO6,___,___,___,___);
  }
  else sound(___,___,___,___,___);
 }
}

 「def.h」は音階の定義ファイル
 下のファイルに同梱してますので欲しければどうぞ

 でもってニコニコ動画に投稿した時のソースがこれ(´・ω・)つ
 なんというか、見る人によってはすごく効率に悪いことしてるなぁと思う方も多いと思いますw
 でもまぁ、当時を考えたらこんなもんかなぁと

 ちょうど東方神風録よりネイティブフェイスの楽譜から打ち込み中に
 「ふぁみおんでネイティブフェイス」とかいう動画が先に上がってランキングインしたもんだから急いでうpしたもんだから
 若干音がおかしい(バグ?)が残った状態で完成させてしまったw(←