PICのプログラムは、主にCCS PIC Cコンパイラーを使用し、たまにアセンブラを使用しています。
PICライターは、秋月電子のAKI-PICプログラマーVer4を使用しました。
PICを使ったクラシックギターの音程をビジュアル的に表示できるチューナーを作成してみようと思い、 いろいろと調べ、また実験を重ねてやっと作成できました。

トランジスタ技術に掲載された幾島康夫さんのH8マイコンを使った
ギター・ピッチ・チューナーをPICで作成できないかと試みてみましたが、
うまくいきませんでした。残念ながら力不足でした。
そこで、ストロボ方式に切り替えて、PICのCCPモジュールのコンペアモードを
使ってビジュアル的に表示できるチューナーを作成しました。何とか使えるものが作成できました。
この回路には、PIC16F873A を使用しました。外観の写真のように左右8個のLED、 計16個の LED を
円形に並べ、その中央にMode表示用の7SEG-LEDを一つ配置し、その下の黒い丸はコンデンサマイクです。
そして右下に、弦選択と基準周波数選択の「Mode切替スイッチ」を、左下に弦選択と基準周波数選択用の
「選択スイッチ」を配置してあります。側面に電源スイッチを付けていますが電源は、9Vの乾電池を
使用しています。
1.「Mode切替スイッチ」が弦選択の時、7SEG表示は次のようになります。
「1」は1弦、「2」は2弦、「3」は3弦、
「4」は4弦、「5」は5弦、「6」は6弦
2.選択スイッチを一度押すごとに1~6までが7SEGに表示されます。
3.「Mode切替スイッチ」が基準周波数選択の時は、以下のように設定してあります。
「1」は439Hz、「2」は440Hz、
「3」は441Hz、「4」は442Hz、
「5」は443Hz、「6」は444Hz、
「7」は445Hz、です。
上記と同様に、選択スイッチを一度押すごとに1~7までが7SEGに表示されます。
4.実際に使用するとき、
(1)左右のLEDの点灯が下方に流れるときは、ギターのピッチが基準周波数より低いときです。
したがって、ギターのピッチを上げます。
(2)左右のLEDの点灯が上方に流れるときは、ギターのピッチが基準周波数より高いときですので、
ギターのピッチを下げます。
(3)ギターのピッチが合っているときは、LEDが点灯したまま流れが止まります。
下記に回路図を表示しておきます。
1.PIC16F873Aを次のように使用しています。
(1)RA0~RA3:1つの7SEG-LEDを表示するためのデコーダ/ドライバ「74HC4511」へ
(2)RA4:モード切替用スイッチへ
(3)RA4:モード切替用スイッチへ
(4)RA5:7SEG-LEDのカウントアップ用プッシュスイッチへ
(5)RB0~RB7:片側LED8個へ
(6)RC0~RC7:もう一方の片側LED8個へ
(7)セラミック発振子は20MHzです。
2.コンデンサマイクからアンプ「LM358」を通し2段のバッファからの出力を上記16個のLEDと
接続しています。
3.電源は9Vの電池を使用しています。
CCPモジュールをコンペアモードで使用し、コンペアレジスタでタイマ1がT/8μSec毎に
割り込みが入るようにして、下図のような信号で8個のLEDを点滅させます。

1.RC0~RC7に接続した8個のLEDも同様に点滅させます。
2.例えば、f=110.0Hzのとき、T=1/f より T=9091μSec となるので、コンペアレジスタで
タイマ1がT/8=1136μSec毎に割り込みが入るようにします。
3.CCP1のCCPRレジスタにタイマ1でT/8μSecの時間カウントになる値をセットしておき、
タイマ1がカウント動作を開始してカウント値が一致したときタイマ1をリセットする
モードにしておけば、タイマ1は、0~CCPRレジスタの値までのカウント動作をずっと
繰り返すことになります。
したがってコンペア一致の割り込みは9091μSec周期で発生することになります。
4.このCCP割込み処理の中でLEDを点滅させ、これとコンデンサマイクの信号を増幅させた
出力とを結合させます。
5.PIC(クロック20MHz)の命令サイクルタイムが0.2μSecですから、タイマ1は、命令サイクル
である0.2μSec毎に+1するので、プリスケーラで1倍とすれば、
(1)0.2μSec×1×count値=9091μSec/8から、count値=5682となります。
(2)基準周波数ごとのcount値を計算した結果を下図に示します。正確には、count値は
計算結果より1を引いています。
黄色の部分をプログラムに使用しています。
ギター・ピッチ・チューナーのPICプログラムを掲載しておきます。
///// Guitar_Modulation /////
#include <16f873A.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay (clock=20000000)
#use fast_io(B)
int icount=0;
int pb_value;
int pc_value;
int Pre_str = 4;
int Pre_fre = 1;
long Cp_count [6][7] = {
{1899,1895,1891,1887,1882,1878,1874},
{2536,2530,2524,2520,2513,2507,2502},
{3195,3188,3180,3174,3166,3159,3152},
{4265,4256,4246,4237,4227,4217,4208},
{5694,5681,5668,5656,5642,5630,5617},
{7601,7583,7566,7550,7532,7515,7498},
};
//// CCP1割り込み処理関数
#int_ccp1 //CCP1の割り込み
void ccp1_isr()
{
icount++;
if (icount>7)
{
pb_value=1;
pc_value=1;
icount=0;
}
else
{
pc_value = input_c();
pb_value = input_b();
pc_value = pc_value<<1;
pb_value = pb_value<<1;
}
output_B(pb_value);
output_C(pc_value);
}
void main()
{
setup_adc_ports(NO_ANALOGS);
set_tris_a(0xF0);
set_tris_b(0);
set_tris_c(0);
output_b(0x01);
output_c(0x01);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); //タイマ1 プリスケーラ1倍で内部クロック動作
setup_ccp1(CCP_COMPARE_RESET_TIMER); //CCP1 コンペアー一致でタイマ1リセット
CCP_1 = Cp_count[Pre_str][Pre_fre];
set_timer1(0); //タイマ1初期セット
enable_interrupts(INT_CCP1); //割り込み許可
enable_interrupts(GLOBAL);
while(1) //アイドルループ
{
if (input(PIN_A4))
{
output_a(Pre_str+1);
if (!input(PIN_A5))
{
Pre_str = Pre_str+1;
if (Pre_str>5)
{
Pre_str=0;
}
output_a(Pre_str+1);
}
delay_ms(400);
}
else
{
output_a(Pre_fre+1);
if (!input(PIN_A5))
{
Pre_fre = Pre_fre+1;
if (Pre_fre>6)
{
Pre_fre=0;
}
output_a(Pre_fre+1);
}
delay_ms(400);
}
CCP_1 = Cp_count[Pre_str][Pre_fre];
}
}
参考としてプリント基板「IC基板」・「LED基板(ケース表面用)」の図2枚とケース内の写真を 掲載しておきます。