前回、78Kマイコンの製作事例プログラムでは、アプリレット・プログラムがほとんどのC言語のソースコードを作ってくれることを説明しました。第2回目は、どのようなソース・コードが作られたのか確認して、動作に必要なソース・コードを追加します。
ボリュームで音の高低が変わる楽器もどきのものは、わずかなソース・コードを追加することでプログラミング可能です。
3.ソース・コードを確認してみる
ここで、ソース・コードが希望の音階の範囲になっているか確認しましょう。ソースコードを確認せずにプログラムを作りたい人は飛ばして4項へ進んでもかまいません。
このあたりを詳しく知るには78K0S/KA1+マイコンのユーザーズ・マニュアルが必要になります。説明するレジスタはどうしても使うマイコンに特有な内容になります。同社の1枚マニュアルから抜粋した図を使って説明します。
(1) タイマH1の設定を確認
音の元となる周波数は方形波のパルスで作ります。そしてそのパルス幅は「入力クロックを何カウントしている間ON状態にするか」ということで作ります。
パルス幅=入力クロックの時間xカウント数
(周波数は「指定したパルス幅時間の2倍」の逆数になる)
ここからは、このマイコン特有の情報になります。カウンタはタイマH1(8ビット長)を使っており、カウントする入力クロックは8MHzです。8MHzクロックでは速すぎるので、セレクタで分周し、これはモード・レジスタで指定します。そのクロック数でパルス幅を決めます。決める値はCMP01レジスタで指定します。この方形波出力を、タイマH1が接続されている出力ポート42に出します。
マイコンのレジスタなので「1枚マニュアル」に書いてある内容を下記に抜粋します。なんとなく、セレクタでCPU発振周波数8MHzクロックを分周して、タイマH1のクロック入力しており、CMP01レジスタで指定された値までカウントして、方形波を出力するということがわかるかと思います。
拡大は画面をクリック
アプリレット・プログラムは、その分周値まで自動で決めています。ソース・ファイルTimer.cには、次のようにTMHD1モードレジスタに分周比とパルス幅のクロック数を指定しています。
TMHMD1 |= ( TM_TMH1_CLOCK << 4 );
CMP01 = TM_TMH1_SQUAREWIDTH;
で、設定した値はヘッダ・ファイルtimer.hに次のように作られてます。
#define TM_TMH1_CLOCK 0x3
#define TM_TMH1_INTERVALVALUE 0x7c
これから、CPUクロック8MHzの分周比として1/64がタイマH1の入力クロックになります。今回カウントの終わり、CMP01レジスタに設定したカウントは7Cつまり10進数で124に設定されています。OFF状態も同じ時間そのままですので、さらに時間は倍、周波数は2分の1から500Hzになっていることがわかります。
方形波の出力周波数 = 8MHz ÷ 64 ÷(124+1)÷2 = 500Hz
この計算で、8ビットのCMP01レジスタが0xFFつまり255になるときに出る最低周波数を計算すると、
8MHz ÷ 64 ÷(255+1)÷2 ≒ 244Hz になります。
これは、1オクターブ下の「ラ」より少し高い値になります。
参考:
16進数から10進数の変換には、Windowsのアクセサリ・プログラムの電卓を関数電卓にして使うと簡単に計算できます。
(2) A-D変換の設定を確認
A-D変換では5Vを8ビット、つまり0~255の値に変換します。変換される電圧の範囲はVCCから抵抗によって高くなった約1Vの電圧間(5V~1V)を変化します。電圧が5V、抵抗が20kΩ VRと4.7kΩ直列ですので、最低の電圧は次の式で決まります。これが28μsごとに読み取り、結果を保存します。変換時間28μsは、先のアプリレット画面で表示されています。
最低電圧値 =(5V × 4.7)÷(20+4.7) ≒ 0.95
これからA-D変換の値は48~255の値になります。
この値を先の周波数計算に入れると次のように、
最低周波数 = 8MHz ÷ 64 ÷ (48+1) ≒ 1275 Hz
1オクターブ上の「ラ」は880Hzなので、この値をタイマH1で使うと合計2オクターブの音階ができそうです。
A-D変換の回路は「1枚マニュアル」の抜粋を載せておきます。ここでは8ビットの変換データは「ADCRHレジスタに入る」とだけ知っておけばよいでしょう。
拡大は画面をクリック
4.ソースを追加してビルドする
実際に動かすための処理、ソース・コードを追加してコンパイルしてみましょう。
まず、PMプラス・プログラムを起動して、アプリレット・プログラムで出力したコードを含むプロジェクトを読み込みます。
そこでソース・コードを追加して、プログラムを完成させることになります。ソースを追加するのは、次の三つのソース・ファイルです。
main.c
Timer_user.c
AD_user.c
これ以外のソース・ファイルは変更する必要がありません。起動画面で左のソース・ファイルを選択して表示します。
(1) メイン・ルーチンmain.cには、次のように2行を追加します。これはタイマH1とA-D変換を開始させるためのコーディングです。
***ソース・コード
unsigned char f_value ;
void main( void )
{
/* TODO. add user code */
TMH1_Start() ;
AD_Start(ADChannel0) ;
while(1){
;
}
}
****
(2) タイマ・ルーチンTimer_user.cの割りこみ処理ルーチン「MD_INTTMH1( void )」には、次のように、タイマをいったん停止させて、1周期ごとにレジスタに周波数値を書き込むコーディングを追加します。f_valueはA-D変換した値が入ってきます。
****ソース・コード
extern unsigned char f_value ;
char inth1 ;
__interrupt void MD_INTTMH1( void )
{
/* TODO */
inth1 ++ ;
if ((inth1 & 1) == 0) {
/*TMH1_Stop();*/
TMHE1 = 0 ;
CMP01 = f_value ;
TMHE1 =1 ;
/*TMH1_Start(); */}
}
*****
(3) A-D変換ルーチンAD_user.cの割り込みルーチン「MD_INTAD( void )」には、次のように、変換結果を周波数を決める変数に入れます。
******ソース・コード
extern unsigned char f_value ;
__interrupt void MD_INTAD( void )
{
/* TODO. Add user defined interrupt service routine */
f_value = ADCRH ;
}
******
これでビルドすると完成です。たった、これだけでプログラムが完成なんです。
フォルダに実行用のHexファイルができます。これを78Kマイコンに書き込めばボリュームで音階が変化する楽器もどきができます。
後田 敏
