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」ここまで。 |