・関連記事
SNESのAPUへDACを接続する
スーファミに使われているDAC(μPD6376)は、MSBファースト2'sコンプリメントです。
MSBファースト2'sコンプリメントのDACであれば、外付けのDACで音を鳴らすことができます。
サンプリング周波数は約32kHzで、市販されているほとんどのDAC(44.1kHzや48kHz)は使用可能です。
今回は様々なDACを接続してみますが、LPFの設計は行いません。
とりあえずはAPU内のLPFと同じ回路で実験してみると良いでしょう。
一部のDACは、LRCK, BCK, DATAの他に、LRCKの倍の周波数(64kHz)であるWCLKが必要なものがあります。APU内S-DSPから直接配線を出す必要があり、多少面倒です。
PT8211
最近秋月電子で発売されたR2Rラダー型DACです。
低価格 & 8ピンSOPのため、実験用に最適です。
LRCKの最大が384kHz(48kHz x 8 オーバーサンプリング)で、デジタルフィルタが使用可能です。
LC7881
20ピンのDIPで、ブレッドボードでの実験用に最適です。
LRCKの最大が176.4kHz(44.1kHz x 4 オーバーサンプリング)で、デジタルフィルタが使用可能です。
WCLK入力が必要で少し面倒です。
CXD8567AN
秋月電子のお楽しみ袋に入っていた謎DACです。
28ピンのSOPで、x8 オーバーサンプリングデジタルフィルタ付きDACです。
データシートはありませんが、ピン配置はCXD2565Mと似ています。
アッテネータ付きなので電子ボリューム的なことができます。
また、ディエンファシス機能もあるため高音の抑制もできます。
ただし、これらの機能を使うにはシリアルコントロールが必要です。
Arduinoプログラム例
//CXD8567AM_コマンド送信
//©oy
//https://oykenkyu.blogspot.com/2022/02/snes-apu-dac.html
#define MODE2_ATT 0x0000 //アッテネートモード
#define MODE2_SYS 0x0002 //システムモード
//アッテネートモード
#define EMP_EN 0x0004 //ディエンファシス有効
#define MUTE_EN 0x0008 //ミュート状態有効
//システムモード
#define IFORM_LSBF 0x0004 //LSBファースト
#define IFORM_MSBF 0x0000 //MSBファースト
#define IBIT_18 0x0008 //18bit_data
#define IBIT_16 0x0000 //16bit_data
#define MT1_60MS 0x0400 //ゼロデータ検出時間60ms
#define MT1_300MS 0x0000 //ゼロデータ検出時間300ms
#define MT2_HMUTE 0x0800 //ゼロミュートフラグの極性"H"でミュート
#define MT2_LMUTE 0x0000 //ゼロミュートフラグの極性"L"でミュート
#define FS_44_1k 0x0000 //ディエンファシスfs=44.1kHz
#define FS_37_8k 0x1000 //ディエンファシスfs=37.8kHz
#define FS_48_0k 0x2000 //ディエンファシスfs=48.0kHz
#define FS_32_0k 0x3000 //ディエンファシスfs=32.0kHz
#define SYNC_EN 0x4000
#define NSMUTE_EN 0x8000
//シリアルデータ出力
void data_out(unsigned int);
//アッテネートデータ生成(MSB-LSB交換)
unsigned int att_gen(unsigned int);
//セットアップ
void setup()
{
unsigned int att_data = 0x0400;//アッテネートデータ
pinMode(2, OUTPUT); //pin2_att_CXD8567AM(3pin)
pinMode(3, OUTPUT); //pin3_shift_CXD8567AM(4pin)
pinMode(4, OUTPUT); //pin4_latch_CXD8567AM(5pin)
digitalWrite(2, LOW);//pin2_att
digitalWrite(3, LOW);//pin3_shift
digitalWrite(4, HIGH);//pin4_latch
//アッテネートデータ出力
data_out(MODE2_ATT | att_gen(att_data));
//システムデータ出力
data_out(MODE2_SYS | IFORM_MSBF | IBIT_16 | MT1_300MS | MT2_LMUTE | FS_32_0k);
}
void loop()
{
}
//シリアルデータ出力
void data_out(unsigned int data){
digitalWrite(4, HIGH);//pin4_latch
for (int i = 15;i >= 0;i--){
digitalWrite(3, LOW);//pin3_shift
delayMicroseconds(10);
digitalWrite(2, (data >> i) & 0x01);//pin2_att
delayMicroseconds(10);
digitalWrite(3, HIGH);//pin3_shift
delayMicroseconds(10);
}
digitalWrite(4, LOW);//pin4_latch
delayMicroseconds(10);
digitalWrite(4, HIGH);//pin4_latch
delayMicroseconds(10);
}
//アッテネートデータ生成(MSB-LSB交換)
unsigned int att_gen(unsigned int att_data){
unsigned int ret_data = 0x0000;
for(int i = 11;i >= 0;i--){
ret_data |= ((att_data >> i) & 0x0001) << (15-i);
}
return ret_data & 0xFFF0;
}
0 件のコメント:
コメントを投稿