BASCOM-AVRの「Sound」命令を使って、ドレミの音階やモールス符号を出力するプログラムを作りました。マイコン回路は「音出し(その1)」と同じです。
音名 | 周波数 | D値 | P値 |
ド | 523Hz | 523 | 157 |
レ | 587Hz | 587 | 140 |
ミ | 659Hz | 659 | 125 |
ファ | 699Hz | 699 | 118 |
ソ | 784Hz | 784 | 103 |
ラ | 880Hz | 880 | 92 |
シ | 988Hz | 988 | 81 |
ド | 1047Hz | 1047 | 77 |
音階の「ドレミファソラシド」を順に1秒間ずつ出力するプログラムです。周波数は「ラ」を880Hzとして計算しました。各音の周波数とD値、P値は左の表の通りです。ただ、実際に音を鳴らしてみると少しずれているように感じたので、P値は修正してあります。原因は計算間違いか私の耳が悪いかのどちらかだと思いますが、深く追求しませんでした。音程の細かい違いを聞き分けるには、圧電スピーカーより普通の8Ωスピーカーの方が適していると思います。
プログラムは下記の通りです。単純に各音用の「Sound」命令を並べただけです。
プログラムファイル afosc3b.bas
1 | $regfile = "at26def.dat" | ATtiny26Lを使用する。 | |
2 | $crystal = 1000000 | クロック周波数を1MHzに設定。 | |
3 | |||
4 | Config Porta = Output | ポートAを出力に設定。 | |
5 | |||
6 | Do | Doループの範囲ここから。 | |
7 | Sound Porta.0 , 523 , 157 | 「ド」の音を1秒間出す。 | |
8 | Sound Porta.0 , 587 , 140 | 「レ」の音を1秒間出す。 | |
9 | Sound Porta.0 , 659 , 125 | 「ミ」の音を1秒間出す。 | |
10 | Sound Porta.0 , 699 , 118 | 「ファ」の音を1秒間出す。 | |
11 | Sound Porta.0 , 784 , 103 | 「ソ」の音を1秒間出す。 | |
12 | Sound Porta.0 , 880 , 92 | 「ラ」の音を1秒間出す。 | |
13 | Sound Porta.0 , 988 , 81 | 「シ」の音を1秒間出す。 | |
14 | Sound Porta.0 , 1047 , 77 | 「ド」の音を1秒間出す。 | |
15 | Loop | Doループの範囲ここまで。6行目へ戻る。 | |
16 | |||
17 | End | 終わり。 |
モールス符号の「CQ」(ツートツート・ツーツートツー)を連続して出すプログラムです。「C」の符号を出力するプログラムと「Q」の符号を出力するプログラムをそれぞれサブルーチンに入れ、順番に呼び出します。短点(ト)の長さは長点(ツー)の1⁄3、各符号間の間隔も長点の1⁄3、「C」と「Q」の間は長点1個分、「CQ」と次の「CQ」の間は長点2個分にしました。正式な決まりは知りませんが、だいたいこんなもんでしょう。
長点の長さを決める変数「D1」の値は「300」(約0.37秒)、短点の長さを決める変数「D2」の値は「100」(約0.12秒)、音程を決める変数「P」の値は「100」(周波数816Hz)にしました。
プログラムファイル afosc3a.bas
1 | $regfile = "at26def.dat" | ATtiny26Lを使用する。 | |
2 | $crystal = 1000000 | クロック周波数を1MHzに設定。 | |
3 | |||
4 | Config Porta = Output | ポートAを出力に設定。 | |
5 | Dim D1 As Word | 長点用変数「D1」を使用する。 | |
6 | Dim D2 As Word | 短点用変数「D2」を使用する。 | |
7 | Dim P As Word | パルス周期用変数「P」を使用する。 | |
8 | D1 = 300 | 変数「D1」の値を「300」にする。 | |
9 | D2 = 100 | 変数「D2」の値を「100」にする。 | |
10 | P = 100 | 変数「P」の値を「100」にする。 | |
11 | |||
12 | Declare Sub Code_c | サブルーチン「Code_c」を使用する。 | |
13 | Declare Sub Code_q | サブルーチン「Code_q」を使用する。 | |
14 | |||
15 | Do | Doループの範囲ここから。 | |
16 | Call Code_c | サブルーチン「Code_c」を呼び出して実行。 | |
17 | Waitms 300 | 300ミリ秒間何もしない。 | |
18 | Call Code_q | サブルーチン「Code_q」を呼び出して実行。 | |
19 | Waitms 600 | 600ミリ秒間何もしない。 | |
20 | Loop | Doループの範囲ここまで。15行目へ戻る。 | |
21 | |||
22 | End | メインプログラム終わり。 | |
23 | |||
24 | Sub Code_c | サブルーチン「Code_c」ここから。 | |
モールス符号「C」を出すプログラム。 | |||
25 | Sound Porta.0 , D1 , P | 長点を出す。 | |
26 | Waitms 100 | 100ミリ秒間何もしない。 | |
27 | Sound Porta.0 , D2 , P | 短点を出す。 | |
28 | Waitms 100 | 100ミリ秒間何もしない。 | |
29 | Sound Porta.0 , D1 , P | 長点を出す。 | |
30 | Waitms 100 | 100ミリ秒間何もしない。 | |
31 | Sound Porta.0 , D2 , P | 短点を出す。 | |
32 | Waitms 100 | 100ミリ秒間何もしない。 | |
33 | End Sub | サブルーチン「Code_c」ここまで。 | |
34 | |||
35 | Sub Code_q | サブルーチン「Code_q」ここから。 | |
モールス符号「Q」を出すプログラム。 | |||
36 | Sound Porta.0 , D1 , P | 長点を出す。 | |
37 | Waitms 100 | 100ミリ秒間何もしない。 | |
38 | Sound Porta.0 , D1 , P | 長点を出す。 | |
39 | Waitms 100 | 100ミリ秒間何もしない。 | |
40 | Sound Porta.0 , D2 , P | 短点を出す。 | |
41 | Waitms 100 | 100ミリ秒間何もしない。 | |
42 | Sound Porta.0 , D1 , P | 長点を出す。 | |
43 | Waitms 100 | 100ミリ秒間何もしない。 | |
443 | End Sub | サブルーチン「Code_q」ここまで。 |