| Ваш IP: 3.239.233.139 | Online(40) - гости: 32, боты: 8 | Загрузка сервера: 0.3 ::::::::::::


DAC CS8416 + AD1852 — 24bit 192kHz (Arduino)(2)

Ранее в https://rcl-radio.ru/?p=86998 рассматривался пример создания внешнего ЦАПа на базе ресивера CS8416 и ЦАП AD1852, в этой статье аналогичный доработанный проект внешнего ЦАПа.

Микросхема AD1852 является однокристальной законченной 18/20/24-разрядной звуковоспроизводящей стерео системой. Она состоит из мультибитного сигма-дельта преобразователя, цифрового интерполяционного фильтра и аналоговой дифференциальной выходной схемы. Кроме этого система включает в себя стерео аттенюатор и устройство отключения звука, которые программируются через последовательный порт SPI. Микросхема AD1852 полностью совместима со всеми известными форматами DVD с частотами дискретизации 192 кГц и 96 кГц, а также с 24-разрядными данными. Для совместимости с устаревшими форматами система также поддерживает цифровую частотную коррекцию 50/15 мкс, использовавшуюся в компакт-дисках «redbook», и компенсацию предыскажений для частот дискретизации 32 кГц и 48 кГц.

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

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

Основные характеристики AD1852:

  • Напряжение питания (AVDD, DVDD) … +5 В
  • Поддержка 24 бит с частотой дискретизации до 192 кГц
  • Отношение сигнал / шум (от 20 Гц до 20 кГц) … 114 дБ
  • Динамический диапазон (от 20 Гц до 20 кГц, вход -60 дБ) … 114 дБ
  • Общие гармонические искажения + шум (стерео) … −102 dB 0.00079 %
  • Управление SPI
  • Фильтр De-emphasis:
    • No De-emphasis
    • 32 kHz
    • 48 kHz
    • 44.1 kHz
  • Выходной формат данных:
    • Left-Justified
    • Right-Justified
    • I2S
  • Разрядность
    • 16 bit
    • 20 bit
    • 24 bit

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

  • Напряжение питания:
    • +3.3 V Analog Supply (VA)
    • +3.3 V Digital Supply (VD)
    • +3.3 V or +5.0 V Digital Interface Supply (VL)
  • Входной формат данных: S/PDIF
  • Выходной формат данных:
    • Left-Justified
    • Right-Justified
    • I2S
  • Разрядность 24 бит
  • Частота дискредитации 192 кГц
  • Фильтр De-emphasis:
    • No De-emphasis
    • 32 kHz
    • 48 kHz
    • 44.1 kHz
  • Кол-во входов: 8
  • Управление: I2C

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

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

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

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

Схема ЦАП на AD1852

Схема ФНЧ на NE5532

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

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

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

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

#define CS    10 // CLATCH
#define MOSI  11 // CDATA
#define SCK   13 // CCLK
 
#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 
 Encoder myEnc(8, 9);//CLK, DT
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
      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;
int db[28]={1,2,3,4,5,6,8,10,12,14,16,19,23,26,29,33,38,43,49,56,63,70,79,86,95,104,116,127};
byte i,d1,d2,d3,d4,d5,d6,e1,e2,e3;
 
 
void setup(){
 Wire.begin();Serial.begin(9600);SPI.begin();Wire.setClock(31000L);
 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("CS8416");
 lcd.setCursor(5,1);lcd.print("AD1852");
 pinMode(CS,OUTPUT);
 pinMode(7,INPUT); // кнопка SW энкодера MENU
 pinMode(6,INPUT_PULLUP); // кнопка IN
 pinMode(5,INPUT_PULLUP); // кнопка MUTE
 vol = EEPROM.read(0);in = EEPROM.read(1);dem = EEPROM.read(2); 
 // Write 8416
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);// 128Fs
  Wire.write (0b00000000 + (dem << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000101);
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(100);
  WriteAD1852(0b100010010001 + (dem << 2) );  // register control 
  WriteAD1852(0b00+(vol<<9)); // register volume left
  WriteAD1852(0b10+(vol<<9)); // register volume right 
  delay(500);lcd.clear();
 }// setup
 
void loop(){
 /// MENU //////////////////////////////
  if(digitalRead(7)==LOW){menu++;if(menu>1){menu=0;};delay(200);lcd.clear();w=1;times=millis();w2=1;}
 /// INPUT /////////////////////////////
  if(digitalRead(6)==LOW){in++;if(in>3){in=0;}delay(200);w=1;times=millis();w2=1;
   // Write 8416
  Wire.beginTransmission(0x10);
  Wire.write (0x00);
  Wire.write (0b00000000);
  Wire.write (0b10000010);// 128Fs
  Wire.write (0b00000000 + (dem << 4));
  Wire.write (0b00000000);
  Wire.write (0b10000000 + (in << 3));
  Wire.write (0b10000101);
  Wire.write (0xFF);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.write (0x00);
  Wire.endTransmission();
  delay(10);
  }
 /// MUTE ///////////////////
 if(digitalRead(5)==LOW&&mute==0){mute=1;code_mute = 0b1000000;delay(200);WriteAD1852(0b100010010001 + (dem << 2) + code_mute );}
 if(digitalRead(5)==LOW&&mute==1){mute=0;code_mute = 0;delay(200);WriteAD1852(0b100010010001 + (dem << 2) + code_mute );} 
 
 /// VOLUME ///////////////////////////////////////////////////
 if(menu==0){
   if (newPosition != oldPosition){oldPosition = newPosition;
     vol=vol+newPosition;myEnc.write(0);newPosition=0;w=1;times=millis();w2=1;
     if(vol>27){vol=27;}if(vol<0){vol=0;}
       WriteAD1852(0b100010010001 + (dem << 2) + code_mute );  // register control 
       WriteAD1852(0b00+(db[vol]<<9)); // register volume left
       WriteAD1852(0b10+(db[vol]<<9)); // register volume right 
       }
 
      lcd.setCursor(0,0);
      if(mute==1){lcd.setCursor(0,0);lcd.print("MUTE   ");}
      if(err==0&&mute==0){lcd.setCursor(0,0);lcd.print("VOLUME ");}
      if(err>0&&mute==0){ lcd.setCursor(0,0);lcd.print("ERROR  ");}
      lcd.setCursor(0,1);lcd.print("COAX ");lcd.print(in+1);
 
if(w2==1){w2=0;
     a[0]=vol/10;a[1]=vol%10;
      for(i=0;i<2;i++){
      switch(i){
        case 0: e1=9,e2=10,e3=11;break;
        case 1: e1=12,e2=13,e3=14;break;
        }
      switch(a[i]){
        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);
 }} 
 } 
 
  /// 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;}
       WriteAD1852(0b100010010001 + (dem << 2) + code_mute );  // register control 
       WriteAD1852(0b00+(db[vol]<<9)); // register volume left
       WriteAD1852(0b10+(db[vol]<<9)); // register volume right 
 
 switch(dem){
  case 0: dem = 0;break;
  case 1: dem = 2;break;
  case 2: dem = 1;break;
  case 3: dem = 3;break;
  }
 
   // Write 8416
       Wire.beginTransmission(0x10);
       Wire.write (0x00);
       Wire.write (0b00000000);
       Wire.write (0b10000010);// 128Fs
       Wire.write (0b00000000 + (dem << 4));
       Wire.write (0b00000000);
       Wire.write (0b10000000 + (in << 3));
       Wire.write (0b10000101);
       Wire.write (0xFF);
       Wire.write (0x00);
       Wire.write (0x00);
       Wire.write (0x00);
       Wire.endTransmission();
       delay(10);
      }
 
  if(w2==1){w2=0;
  lcd.setCursor(0,0);lcd.print("DE-EMPHASIS SEL");  
  lcd.setCursor(0,1);
  switch(dem){
  case 0: lcd.print("No De-emphasis");break;
  case 1: lcd.print("44.1 kHz      ");break;
  case 2: lcd.print("32.0 kHz      ");break;
  case 3: lcd.print("48.0 kHz      ");break;
  }}}
 
 
////////// cs8416 read  
  if(millis()-times1>1000){times1=millis();err = wireRead(0x10,0x0C);delay(10);}
  if(err!=err_old){err_old = err;w2=1;}
 
 
  if(millis()-times>5000 && w==1){w=0;EEPROM.update(0,vol);EEPROM.update(1,in);EEPROM.update(2,dem);menu=0;lcd.clear();w2=1;}
 
  }// loop
 
 
void WriteAD1852(uint16_t Data){
  for(int p=0;p<2;p++){
  SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV16, MSBFIRST, SPI_MODE3));
  digitalWrite(CS, HIGH);
  delayMicroseconds(10);
  SPI.transfer16(Data);
  digitalWrite(CS, LOW);
  SPI.endTransaction();
}}  
 
byte wireRead(int addr, int reg){
  Wire.beginTransmission(addr);
  Wire.write (reg);
  Wire.endTransmission();
  delay(10);
  Wire.requestFrom(addr,1);
  while(Wire.available()<1);
  byte value = Wire.read();
  return value;
  }  
 
void to_Timer(){newPosition = myEnc.read()/4;}

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

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

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

  • Контроль уровня воды в аквариуме

    Схема контроля уровня воды в аквариуме представлена на рис.1. Как только поверхность специального зонда покрывается водой, импульсы генератора НЧ, реализованного на первом операционном усилителе D1.1, поступают на компаратор (D1.2), усиливаются и преобразуются в электрический сигнал, управляющий ключевым каскадом на реле К1. В качестве датчика зонда В1 используется отрезок одно или …Подробнее...
  • Передатчик на 27МГц для системы радиоуправления

    Генератор радиопередатчика собран на схеме кварцевой стабилизации частоты. L1C3 настроен на 27 МГц. Радиус действия передатчика 5…10м. Модуляция осуществляется с выхода микросхемы 561 серии напряжением на уровне 5-7В. Литература 500схем для радиолюбителей\Автор:Николаев А.П.Подробнее...
  • Усилитель мощности на диапазон 144 МГц

    Данный усилитель предназначен для усиления мощности передатчика карманной радиостанции в диапазоне 144 МГц. При подачи на его вход сигнала мощностью 0,05Вт и питании 24В усилитель выдает мощность 5-6Вт, а при питании его напряжением 12В он выдает 3-4Вт. Входное и выходное сопротивления равны 50 Ом. Описание: первый каскад работает в классе …Подробнее...
  • 4-х канальный УМЗЧ на TDA7385

    4-х канальный УМЗЧ на TDA7385

    На ИМС TDA7385 можно собрать простой и качественный 4-х канальный усилитель мощности звуковой частоты. Усилитель прост в сборке, так как имеет минимальный набор внешних компонентов, не нуждается в настройке. Основные характеристики усилителя на TDA7385: Максимальное напряжение питания 18 В Ток покоя 180 мА Выходная мощность при напряжении питания 14,4 В …Подробнее...
  • К1156ЕР5х — РЕГУЛИРУЕМЫЙ ПРЕЦИЗИОННЫЙ ПАРАЛЛЕЛЬНЫЙ СТАБИЛИЗАТОР

    К1156ЕР5х — РЕГУЛИРУЕМЫЙ ПРЕЦИЗИОННЫЙ ПАРАЛЛЕЛЬНЫЙ СТАБИЛИЗАТОР

    Микросхема серии К1156ЕР5х представляет собой трехвыводной регулируемый прецизионный параллельный стабилизатор с высокой температурной стабильностью. Аналогом микросхемы К1156ЕР5х является микросхема TL431 фирм MOTOROLA, TEXAS INSTRUMENTS. Назначение выводов: 1- опорное напряжение 2- анод 3- катод ОСОБЕННОСТИ • Опорное напряжение 2495 мВ ± 1%; • Типовое значение изменения опорного напряжения 5 мВ в рабочем диапазоне температур; • Типовое значение …Подробнее...