
写真1 AD9833 DDS MSOP 0.5ピッチ 変換基板に乗せる
それはさておき、
このチップは10ピンのMSOPで、写真にようにピンセットの先ほどの大きさです。
変換基板に取り付けましたが、ピンのピッチは0.5なので、半田付けにはちょっと技術が必要です。
まずチップをゲルタイプの瞬間接着剤で正確な位置に仮止めしておきます。
フラックスをほんのわずか塗って、すべてのピンにわざとまたがるくらい半田を盛ります。
半田吸い取り線で、余分な半田を吸い取って、出来上がり。
慣れれば簡単ですが、最初は数個パーにする覚悟がいります(笑)。
このDDSは、マスタクロック(MCLK)周波数は最高25MHzで、その場合最高発振周波数(ナイキスト周波数)は12.5MHzとなり、分解能は0.1Hzです。
今回は手持ち部品の関係で、20MHzのクリスタルを使用したので、10MHzまでのプログラマブルオシレータとして、実験してみました。この場合の分解能は約0.075Hzです。

青木直史氏の「C言語ではじめる 音のプログラミング」を参考にして、サイン波のWAVファイルをmbedで作ってみました。
サイン波は基本周波数(fo)と振幅(A)を指定すると、
サンプリング周波数(Fs)として
s(n) = A sin((2π*fo*n)/fs) で計算できます。
nを0から40000まで変化させれば約5秒のWAVファイルが作れます。
プログラムは、サンプリング周波数を8KHzとしていますので、音質は電話レベルです。
量子化精度は16bitsです。
mbedはメモリに制限があるので、alloc()であまり大きなメモリエリアは確保できません。このためここでは1000 double wordsを1ブロックとして、再利用しています。
周波数FREQ、振幅AMPを指定して、出力ファイルのファイル名を後でわかりやすいものに変更しておき、コンパイルします。
ここでは440Hz(ラの音)で振幅0.5としています。
出力ファイルはmbedのローカルファイルとして作成しますので、PCからMediaPlayerで聴くことができます。
フリーソフトのSoundEngineでも確認することができます。
回路図

SoundEngineで聴いてみた
周波数440Hzの正弦波 サンプリング周波数8Hz、量子化精度16Bits、5秒
/*This program is made in reference to "Sound Programming in C Language" by Aoki Naofumi"*/
#define FREQ 440 //Frequency (Hz)
#define AMP 0.5 //Amplitude 0 - 1
#define FILE_NAME "/local/440_05.wav" //Data file name max 8char.wav fffff_aa.wav
#include "mbed.h"
#include "TextLCD.h"
TextLCD lcd(p24, p26, p27, p28, p29, p30);
LocalFileSystem local("local" );
DigitalOut led_1(LED1);
DigitalOut led_2(LED2);
DigitalOut led_3(LED3);
DigitalOut led_4(LED4);
int main(void)
{
typedef struct
{
int fs;
int bits;
int length;
double *s;
} MONO_PCM;
FILE *fp;
MONO_PCM pcm;
int i, j;
double s;
short data;
double A, f0;
char riff_chunk_ID[4];
long riff_chunk_size;
char riff_form_type[4];
char fmt_chunk_ID[4];
long fmt_chunk_size;
short fmt_wave_format_type;
short fmt_channel;
long fmt_samples_per_sec;
long fmt_bytes_per_sec;
short fmt_block_size;
short fmt_bits_per_sample;
char data_chunk_ID[4];
long data_chunk_size;
lcd.cls();
lcd.locate(0,0);
lcd.printf("Audio wave\n" );
int block_length = 1000;
pcm.fs = 8000;
pcm.bits = 16;
pcm.length = 40000; //about 5sec
pcm.s = (double*) calloc(block_length, sizeof(double));
A = AMP;
f0 = FREQ;
if ( NULL == (fp = fopen(FILE_NAME, "wb" )) )
error( "" );
led_1 = 1;
riff_chunk_ID[0] = 'R';
riff_chunk_ID[1] = 'I';
riff_chunk_ID[2] = 'F';
riff_chunk_ID[3] = 'F';
riff_chunk_size = 36 + pcm.length * 2;
riff_form_type[0] = 'W';
riff_form_type[1] = 'A';
riff_form_type[2] = 'V';
riff_form_type[3] = 'E';
fmt_chunk_ID[0] = 'f';
fmt_chunk_ID[1] = 'm';
fmt_chunk_ID[2] = 't';
fmt_chunk_ID[3] = ' ';
fmt_chunk_size = 16;
fmt_wave_format_type = 1;
fmt_channel = 1;
fmt_samples_per_sec = pcm.fs;
fmt_bytes_per_sec = pcm.fs * pcm.bits / 8;
fmt_block_size = pcm.bits / 8;
fmt_bits_per_sample = pcm.bits;
data_chunk_ID[0] = 'd';
data_chunk_ID[1] = 'a';
data_chunk_ID[2] = 't';
data_chunk_ID[3] = 'a';
data_chunk_size = pcm.length * 2;
fwrite(riff_chunk_ID, 1, 4, fp);
fwrite(&riff_chunk_size, 4, 1, fp);
fwrite(riff_form_type, 1, 4, fp);
fwrite(fmt_chunk_ID, 1, 4, fp);
fwrite(&fmt_chunk_size, 4, 1, fp);
fwrite(&fmt_wave_format_type, 2, 1, fp);
fwrite(&fmt_channel, 2, 1, fp);
fwrite(&fmt_samples_per_sec, 4, 1, fp);
fwrite(&fmt_bytes_per_sec, 4, 1, fp);
fwrite(&fmt_block_size, 2, 1, fp);
fwrite(&fmt_bits_per_sample, 2, 1, fp);
fwrite(data_chunk_ID, 1, 4, fp);
fwrite(&data_chunk_size, 4, 1, fp);
wait(0.5);
led_1 = 0;
led_2 = 1;
for(i = 0; i < pcm.length/block_length; i++)
{
for (j = 0; j < block_length; j++)
{
pcm.s[j] = A * sin(2.0 * 3.141592 * f0 * (i * block_length + j) / pcm.fs);
s = (pcm.s[j] + 1.0) / 2.0 * 65536.0;
if (s > 65535.0) s = 65535.0;
else if (s < 0.0) s = 0.0;
data = (short)(s + 0.5) - 32768;
fwrite(&data, 2, 1, fp);
}
}
led_2 = 0;
fclose(fp);
free(pcm.s);
lcd.locate(0,1);
lcd.printf("Done!\n" );
return 0;
}
http://mbed.org/users/jf1vrr/programs/audio_wave/lq3n6g
(JF1VRR)