| Ваш IP: 3.238.186.43 | Online(40) - гости: 25, боты: 15 | Загрузка сервера: 2.96 ::::::::::::

DAC WM8804 + AK4396 — 24bit 192kHz (Arduino)

Внешний звуковой ЦАП собран на недорогих компонентах, в качестве ресивера используется WM8804, ЦАП на AK4396. ЦАП имеет микроконтроллерное управление на базе платформы Arduino.

Входной цифровой сигнал для внешнего ЦАПа имеет формат S/PDIF (цифровой аудио интерфейс разработанный фирмами SONY/PHILIPS, предназначен для передачи цифрового сигнала между аудио устройствами), ресивер на WM8804 преобразует его в формат I2S 24 бит с частотой дискретизации 192 кГц. Цифровой сигнала I2S поступает на ЦАП AK4396, далее с выхода AK4396 звуковой сигнал поступает на фильтр-сумматор собранный на ОУ NE5532.

Для нормальной работы ресивер и ЦАП должный иметь одинаковый формат передачи цифровых данных, в данном случае это I2S 24 бит с частотой дискретизации 192 кГц.

Параметры ресивера WM8804:

  • Напряжение питания:
    • +3.3 V DVDD
    • +3.3 V PVDD
  • Входной формат данных: S/PDIF
  • Выходной формат данных:
    • I2S (аппаратно настроен)
    • Left Justified
    • Right Justified
  • Разрядность 16/20/24 бит (аппаратно настроен на 24 бит)
  • Частота дискредитации 32 to 192 кГц (аппаратно настроен на 192 кГц)
  • MCLK rate of 512fs, 256fs, 128fs и 64fs

Параметры ЦАП на AK4396:

  • Напряжение питания:
    • +5 V Analog Supply
    • +5 V Digital Supply
  • Входной формат данных: I2S (PCM)
  • Разрядность 24 бит
  • Частота дискредитации 192 кГц
  • Фильтр De-emphasis:
    • No De-emphasis
    • 32 kHz
    • 48 kHz
    • 44.1 kHz
  • Roll-off Filter
    • Sharp roll-off filter
    • Slow roll-off filter
  • Аттенюатор 75 дБ (256 ступеней — линейная зависимость)
  • Режим MUTE
  • Отношение сигнал\шум 120 дБ
  • Динамический диапазон 120 дБ
  • Уровень нелинейных искажений -100 дБ

Внешний ЦАП состоит из нескольких компонентов:

  • Ресивер на WM8804
  • ЦАП на AK4396
  • ФНЧ на NE5532
  • Источник питания
  • Плата Arduino Nano
  • Индикатор LCD1602 с модулем I2C
  • Энкодер KY-040
  • Кнопка — MUTE

Управление внешним ЦАПом осуществляется при помощи энкодера, кнопка энкодера позволяет переключаться между меню «VOLUME»,  «De-emphasis SEL» и «Roll-off Filter», поворот ручки энкодера меняет настройки выбранного параметра. Дополнительно используются кнопка MUTE. Вся информация выводится на индикатор LCD1602 ( с модулем I2C). Громкость имеет 37 шагов (логарифмическая зависимость).

Схема ресивера на WM8804

Схема ЦАП на AK4396

Схема ФНЧ на NE5532

Схема управления

Для питания внешнего ЦАПа рекомендуется использовать три независимых источника питания, который состоит из одного трансформатора с тремя независимыми вторичными обмотками,  одна из которых имеет отвод от середины для двух полярного источника питания. Каждый источник питания имеет свой диодный мост. При этом аналоговая и цифровая земля объединяются через дроссель. Дополнительно как можно ближе к микросхемам по цепи питания устанавливаются фильтрующие конденсаторы.

Схема источника питания (стабилизаторы)

Упрощенная схема источника питания (стабилизаторы)

#define CS    10 // CSN  AK4396
#define MOSI  11 // CDTI AK4396
#define SCK   13 // CCLK AK4396
#define RES    2 // PDN  AK4396
 
#include <SPI.h>
#include <EEPROM.h>
#include <MsTimer2.h>                    // https://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <Encoder.h>                     // https://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <LiquidCrystal_I2C.h>           // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1 
 LiquidCrystal_I2C lcd(0x27,16,2);       // Устанавливаем дисплей 
 Encoder myEnc(9, 8);//CLK, DT
      byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07};
      byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00};      
      byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F};
      byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F};
      byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C};
      byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C};
      byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07};
      byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00};
      unsigned long times,oldPosition  = -999,newPosition,times1;
      int w,vol,mute,code_mute,in,w2,a[3],menu,dem,err,err_old,roll;
      int db[38]={0,1,2,3,4,5,6,7,8,9,10,11,13,15,17,19,22,25,28,32,36,40,45,51,57,64,72,80,90,100,112,126,142,159,178,200,224,255};
      byte u,d1,d2,d3,d4,d5,d6,e1,e2,e3;
 
 
void setup(){
 Wire.begin();SPI.begin();
 lcd.init();lcd.backlight();
 lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);
 MsTimer2::set(1, to_Timer);MsTimer2::start();
 if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении 
 lcd.setCursor(5,0);lcd.print("WM8804");
 lcd.setCursor(5,1);lcd.print("AK4396");
 pinMode(CS,OUTPUT);
 pinMode(RES,OUTPUT);
 pinMode(5,INPUT_PULLUP); // кнопка MUTE
 pinMode(7,INPUT); // кнопка SW энкодера MENU
 vol = EEPROM.read(0);dem = EEPROM.read(2); roll = EEPROM.read(3);
 delay(1000);
 digitalWrite(RES,HIGH);ak();lcd.clear(); // AK4396 ON
 }// setup
 
void loop(){
/// MENU //////////////////////////////
 if(digitalRead(7)==LOW){menu++;if(menu>2){menu=0;};delay(100);lcd.clear();w=1;times=millis();w2=1;}  
 
/// MUTE ///////////////////
 if(digitalRead(5)==LOW&&mute==0&&menu==0){mute=1;delay(200);WriteAK4396(0b0010001100000000);WriteAK4396(0b0010010000000000);}
 if(digitalRead(5)==LOW&&mute==1&&menu==0){mute=0;delay(200);WriteAK4396(0b0010001100000000 + db[vol]);WriteAK4396(0b0010010000000000 + db[vol]);} 
 
/// VOLUME ///////////////////////////////////////////////////
 if(menu==0){
   if (newPosition != oldPosition){oldPosition = newPosition;
     vol=vol+newPosition;myEnc.write(0);newPosition=0;w=1;times=millis();w2=1;w=1;mute=0;
     if(vol>37){vol=37;}if(vol<0){vol=0;}
     ak();}
 
      lcd.setCursor(0,0);
      if(mute==1){lcd.print("MUTE   ");}else{lcd.print("VOLUME ");}
      lcd.setCursor(0,1);
      switch(dem){
        case 1: lcd.print("OFF ");break;
        case 0: lcd.print("44.1");break;
        case 3: lcd.print("32.0");break;
        case 2: lcd.print("48.0");break;}
     switch(roll){
        case 0: lcd.print("Sharp");break;
        case 1: lcd.print("Slow ");break;}   
 
 
if(w2==1){w2=0;
     a[0]=vol/10;a[1]=vol%10;
      for(u=0;u<2;u++){
      switch(u){
        case 0: e1=9,e2=10,e3=11;break;
        case 1: e1=12,e2=13,e3=14;break;
        }
      switch(a[u]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 }} 
 } // volume end
 
  /// DE-EMPHASIS //////////////////////////////////
  if(menu==1){
     if (newPosition != oldPosition){oldPosition = newPosition;
     dem=dem+newPosition;myEnc.write(0);newPosition=0;w=1;times=millis();w2=1;
      if(dem<0){dem=3;}if(dem>3){dem=0;}
      ak();
      }
  if(w2==1){w2=0;
  lcd.setCursor(0,0);lcd.print("DE-EMPHASIS SEL");  
  lcd.setCursor(0,1);
  switch(dem){
  case 1: lcd.print("No De-emphasis");break;
  case 0: lcd.print("44.1 kHz      ");break;
  case 3: lcd.print("32.0 kHz      ");break;
  case 2: lcd.print("48.0 kHz      ");break;
  }}}
 
   /// Roll-off Filter //////////////////////////////////
  if(menu==2){
     if (newPosition != oldPosition){oldPosition = newPosition;
     roll=roll+newPosition;myEnc.write(0);newPosition=0;w=1;times=millis();w2=1;
      if(roll<0){roll=1;}if(roll>1){roll=0;}
      ak();
      }
  if(w2==1){w2=0;
  lcd.setCursor(0,0);lcd.print("Roll-off Filter");  
  lcd.setCursor(0,1);
  switch(roll){
  case 0: lcd.print("Sharp");break;
  case 1: lcd.print("Slow ");break;
  }}}  
 
 if(millis()-times>5000 && w==1){w=0;EEPROM.update(0,vol);EEPROM.update(2,dem);EEPROM.update(3,roll);menu=0;lcd.clear();w2=1;}
 delay(100);
  }// loop
 
 
void WriteAK4396(uint16_t Data){
  for(int p=0;p<2;p++){
  SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV16, MSBFIRST, SPI_MODE0));
  digitalWrite(CS, LOW);
  delayMicroseconds(10);
  SPI.transfer16(Data);
  digitalWrite(CS, HIGH);
  SPI.endTransaction();
}} 
 
void ak(){
  WriteAK4396(0b0010000000000111);  //  control 00H
  WriteAK4396(0b0010000100010010 + (dem << 1) + (roll << 5));  //  control 01H -- [4:3]=10 120-216kHz -- [2:1]=dem off/44.1/32/48 -- [5]=roll
  WriteAK4396(0b0010001000000000);  //  control 02H
  WriteAK4396(0b0010001100000000 + db[vol]); // volume left  03H
  WriteAK4396(0b0010010000000000 + db[vol]); // volume right 04H
  }
void to_Timer(){newPosition = myEnc.read()/4;}

Добавить комментарий

Войти с помощью: 

Случайные статьи

  • Светодиодный драйвер 2Вт на таймере 555

    Светодиодный драйвер 2Вт на таймере 555

    На рисунке показана схема простого драйвера светодиода, с напряжение питания от 3 до 18В. Основу устройства составляет таймер 555 или  LMC555 на напряжение 5В. На таймере 555 собран ШИМ — регулятор выходной мощности драйвера. Светодиоды суммарной мощностью 2Вт подключены через MOSFET транзистор IRLU3802PBF. Радиатор транзистору не нужен, но если необходима дополнительная мощность (более …Подробнее...
  • Условные графические обозначения электрических машин

    А. Элементы электрических машин (табл.1) 1. Обмотка: а) общее обозначение; б) параллельного возбуждения; в) последовательного возбуждения; г) компенсационная; д) вспомогательного полюса. 2. Статор, общее обозначение. 3. Ротор: а) общее обозначение, короткозамкнутый; б) без обмотки полый немагнитный или ферромагнитный; в) без обмотки с явно выраженными полюсами (с прорезями по окружности); г) …Подробнее...
  • Предусилитель на 3 микрофона

    Предусилитель на 3 микрофона

    Схема приведенная здесь имеет три микрофонных входа, схема выполнена на микросхеме LM348 IC.LM348 обладает высоким коэффициентом усиления, схема выполнена на четырех операционных усилителя с выходным каскадом класса AB. Микросхемы имеет очень низкий ток покоя (0.6mA) и работают от двухполярного источника питания. Заметки. * Сборка схемы на хорошее качество печатной плате. …Подробнее...
  • MP7720 — миниатюрный усилитель класса D

    MP7720 — миниатюрный усилитель класса D

    На микросхеме MP7720 можно собрать миниатюрный усилитель класса D. Особенностью данной микросхемы является отсутствие радиатора охлаждения, так КПД микросхемы более 90%, что позволяет уменьшить размеры конечного устройства. Характеристики усилителя: встроенная система устранения акустических щелчков включения/выключения встроенная защита от короткого замыкания выходная мощность на нагрузке 4 Ом 20 Вт при напряжении …Подробнее...
  • УМЗЧ 2*20Вт на LA4450

    УМЗЧ 2*20Вт на LA4450

    На рисунке показана схема двухканального усилителя мощности звуковой частоты на ИМС LA4450. Выходная мощность усилителя при напряжении питания 26,4В (рекомендованное) 12Вт (на канал) на нагрузке 8 Ом и 20 Вт (на канал) на нагрузке 4 Ом. ИМС LA4450 имеет тепловую защиту, защиту от перенапряжения и импульсных помех. Основные характеристики Максимальное напряжение …Подробнее...