目次
前
次
音出し
書籍の付録には、スピーカがひとつ入っていました。
大きくて実験では、扱い難いので¥100ショップで
売られているスピーカを利用します。
スピーカのインピーダンスは、4Ωから16Ω程度で
マイコンの出力ポートにとっては、重い負荷なので
バッファのトランジスタを入れて電流増幅して使い
ます。
スピーカに波形を送れば音がでます。
PWM波形を与えることで、音色が変化します。
PWM波形の場合、HとLレベルの時間比率をDuty比として
定義して処理します。
実験回路は、以下。
実験回路の動作テストは、以下のプログラムを利用。
#define OFF 0
#define ON OFF+1
#define THX 1000
typedef unsigned char UBYTE ;
UBYTE state ;
/* prototype */
void usr_init(void);
void main(void)
{
/* initialize PORT */
usr_init();
/* endless loop */
while (ON) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(THX);
/* update state */
state++ ;
}
}
void usr_init(void)
{
/* initial value */
PORTB = OFF ;
/* direction */
TRISB = 0x00 ;
/* clear state counter */
state = 0 ;
}
スイッチを押している間、スピーカから音が出るように
してみます。
#define OFF 0
#define ON OFF+1
#define THX 1000
typedef unsigned char UBYTE ;
UBYTE state ;
/* prototype */
void usr_init(void);
void main(void)
{
/* initialize PORT */
usr_init();
/* endless loop */
while (ON) {
/* beep */
while ( PORTA.FO == OFF ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(THX);
/* update state */
state++ ;
}
}
}
void usr_init(void)
{
/* initial value */
PORTA = OFF ;
PORTB = OFF ;
/* direction */
TRISA = 0xff ;
TRISB = 0x00 ;
/* clear state counter */
state = 0 ;
}
この回路の応用は、アマチュア無線で利用される
電鍵と紹介されています。GHD社縦振電鍵が有名。
モールス符号(CW)は、次のようになっています。
A . -
B - . . .
C - . - .
D - . .
E .
F . . - .
G - - .
H . . . .
I . .
J . - - -
K - . -
L . - . .
M - -
N - .
O - - -
P . - - .
Q - - . -
R . - .
S . . .
T -
U . . -
V . . . -
W . - -
X - . . -
Y - . - -
Z - - . .
1 . - - - -
2 . . - - -
3 . . . - -
4 . . . . -
5 . . . . .
6 - . . . .
7 - - . . .
8 - - - . .
9 - - - - .
0 - - - - -
電鍵の場合、2個のスイッチを用意してdot(.)
dash(-)を表現するパドルもあります。
(写真は、GHD社のパドルです。)
3箇所のスイッチにより、音色が変化するように
プログラムすると、次のようになります。
#define OFF 0
#define ON OFF+1
#define SF0 477
#define SF1 425
#define SF2 380
typedef unsigned char UBYTE ;
UBYTE state ;
/* prototype */
void usr_init(void);
void main(void)
{
/* initialize PORT */
usr_init();
/* endless loop */
while (ON) {
/* SF0 */
while ( PORTA.FO == OFF ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(SF0);
/* update state */
state++ ;
}
/* SF1 */
while ( PORTA.F1 == OFF ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(SF1);
/* update state */
state++ ;
}
/* SF2 */
while ( PORTA.F2 == OFF ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(SF2);
/* update state */
state++ ;
}
}
}
void usr_init(void)
{
/* initial value */
PORTA = OFF ;
PORTB = OFF ;
/* direction */
TRISA = 0xff ;
TRISB = 0x00 ;
/* clear state counter */
state = 0 ;
}
回路は、以下。
複数のピッチの音を出して、メロディを出すこともできます。
CDEFGABの各ピッチを生成する関数を定義して、対応します。
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
typedef unsigned short UWORD ;
UBYTE state ;
/* prototype */
void usr_init(void);
void n_c(void);
void n_d(void);
void n_e(void);
void n_f(void);
void n_g(void);
void n_a(void);
void n_b(void);
void n_cc(void);
void n_r(void);
void main(void)
{
/* initialize PORT */
usr_init();
/* endless loop */
while (ON) {
/* */
n_c();n_c();n_c();n_c();n_c();n_c();n_d();n_d();n_e();n_e();n_d();n_d();
n_c();n_c();n_r();n_r();n_r();n_r();
/* */
n_d();n_d();n_d();n_d();n_d();n_d();n_g();n_g();n_d();n_d();n_g();n_g();
n_e();n_e();n_r();n_r();
/* */
n_e();n_e();n_f();n_f();n_g();n_g();n_g();n_g();n_d();n_d();n_e();n_e();
n_f();n_f();n_f();n_f();
/* */
n_r();n_r();
/* */
n_g();n_g();n_g();n_g();n_g();n_g();n_g();n_g();n_g();n_g();n_f();n_f();
n_e();n_e();n_d();n_d();n_c();n_c();n_c();n_r();n_r();n_r();
}
}
void usr_init(void)
{
/* initial value */
PORTA = OFF ;
PORTB = OFF ;
/* direction */
TRISA = 0xff ;
TRISB = 0x00 ;
/* clear state counter */
state = 0 ;
}
void n_c(void)
{
UBYTE i ;
for ( i = 0 ; i < 150 ; i++ ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(477);
/* update state */
state++ ;
}
}
void n_d(void)
{
UBYTE i ;
for ( i = 0 ; i < 168 ; i++ ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(425);
/* update state */
state++ ;
}
}
void n_e(void)
{
UBYTE i ;
for ( i = 0 ; i < 189 ; i++ ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(379);
/* update state */
state++ ;
}
}
void n_f(void)
{
UBYTE i ;
for ( i = 0 ; i < 200 ; i++ ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(358);
/* update state */
state++ ;
}
}
void n_g(void)
{
UBYTE i ;
for ( i = 0 ; i < 225 ; i++ ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(318);
/* update state */
state++ ;
}
}
void n_a(void)
{
UBYTE i ;
for ( i = 0 ; i < 252 ; i++ ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(284);
/* update state */
state++ ;
}
}
void n_b(void)
{
UWORD i ;
for ( i = 0 ; i < 282 ; i++ ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(253);
/* update state */
state++ ;
}
}
void n_cc(void)
{
UWORD i ;
for ( i = 0 ; i < 300 ; i++ ) {
/* impress */
PORTB = state & ON ;
/* delay */
Delay_ms(239);
/* update state */
state++ ;
}
}
void n_r(void)
{
UWORD i ;
for ( i = 0 ; i < 567 ; i++ ) {
/* impress */
PORTB = OFF ;
/* delay */
Delay_ms(126);
}
}
ピッチは、単位時間あたりの波の数なので
for文で繰返回数を決めています。
目次
前
次