PIC12F1822 という8ピンの小さなPICを使い、PWM(パルス幅変調)出力のオルゴールを作ります。

 

完成するとこんな音が出ます。

 

 

 

電子オルゴールを作ってみたいけど、オルゴールの原理がわからない、PIC用のプログラムを書いたことがない、アセンブラ言語がわからない、といった人向けに、和音出力へ改修想定したプログラム(単音が出るコード)を公開します。

 

ディアゴスティーニ式で、全部のプログラムをつなげる(行番号が付いている)と頭を使わなくてもオルゴールが完成します。

内容をよく理解すると3和音出力のプログラムへステップアップできるかも知れません。

 

では、プログラム1行目から

 

1行目 list p=~ は、コンパイルリスト(.lst)を出力するための記述で、このプログラムがPIC12F1822用であることをコンパイラに教えるためのもの。この記述がなくてもプログラムは動きます。

 

2行目 errorlevel は、コンパイル時にバンクセレクトに関連するワーニングを出さなくするもの。アセンブラでは対象となるアドレスが実行時に選択されているメモリバンクによって変わってしまうため、コンパイラがおせっかいを焼きます。BANKSEL文を使ってバンクを常に気をつけて書いている人にとっては煩わしいためこの記述を入れます。なくてもプログラムは動きます。

 

3行目 #include で PIC12F1822 用の定義の数々がまとめられたファイルを取り込みます。マイクロチップの開発環境(IDE)のインストール先にp12f1822.inc というテキストファイルがあるはずなので中身を見ておくととてもためになります。

 

4、5行目 __CONFIG は、PICの動作を決めるコンフィギュレーションレジスタの設定になります。2つあるので2つ分設定します。上記インクルードファイル(.inc)中に定義があるのでそれを利用します。.inc ファイルの中身を見なくても IDE のメニューConfigure -> Configuration Bits から設定することも可能です。

 

8~12行目 cblock ~ endc は定数定義ブロック(Constant Block)で、列挙した定数が、この場合0x40から順に割り当てられます。割り当てに際してデータサイズも付記できます。Tone0は0x40、Lngt0は0x42、Accm0は0x44、RnAc0は0x47になります。

3和音を想定して構造体3つ分のような定義にしています。以降定義していくサブルーチンはこの構造1つ分を見て働きかけるようにしています。ちなみにPIC12F1822の場合、 0x20 ~ 0x6F は General Purpose RAM 、0x70~0x7F は Common RAM となっていて、CommonRamはどのバンクからでも読み書きできます。

 

13~24行目 EQU は、プログラム中で使いたい変数のアドレス割り当てを行っています。EQUはただの置き換えなので今回はアドレス割り当てに利用したまで。24行目は定数定義のために使っています。

 

26~27行目 ORG 0x0000 PICはリセットがかかると0x0000番地からプログラムが実行開始されます。プログラム0x0000番地にGOTOを書いて自分のプログラムを開始させます。

 

28~29行目 ORG 0x0004 PICが割り込みを受けると0x0004番地に実行が割り込まれます。0x0004番地にGOTOを書いて、自分の割り込みルーチンへ飛ぶように仕掛けます。

 

30~33行目 割り込みルーチンの記述。今回は中身が空っぽですが、ボタンを押したり、タイマ満了を受けたり等の処理を書きます。割り込みから復帰するときは、RETURN ではなく RETFIE (Return From Interrupt)を使います。