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

DAC PCM1796 + CS8416 (Arduino)

Внешний ЦАП собран за базе ЦАП PCM1796 который обладает весьма качественными характеристиками. Управление параметрами ЦАП PCM1796 микроконтроллерное, осуществляется при помощи платы Arduino Nano, позволяющее изменять громкость, активировать режим MUTE, применять цифровые фильтры Rolloff и De-Emphasis. Ресивер S/PDIF собран на CS8416.

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

Параметры ресивера 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 (аппаратно настроен)
  • Разрядность 16 — 24 бит (аппаратно настроен на 24 бит)
  • Частота дискредитации 32 — 192 кГц (аппаратно настроен на 192 кГц)
  • Фильтр De-emphasis:
    • No De-emphasis (аппаратно настроен)
    • 32 kHz
    • 48 kHz
    • 44.1 kHz
  • Кол-во входов: 8 (аппаратно поддерживает 4, настроен на 1 канал)

Параметры ЦАП на PCM1796

  • Напряжение питания
    • 5-V Analog
    • 3.3-V Digital
  • Входной формат данных:
    • Left-Justified
    • Right-Justified
    • I2S (программно настроен)
  • Частота дискредитации: 10 кГц to 200 кГц
  • System Clock: 128, 192, 256, 384, 512, or 768 fS With Autodetect
  • Коэффициент гармоник с учетом шума (THD+N): 0.0005%
  • Динамический диапазон 123 дБ
  • Отношение сигнал.шум 123 дБ
  • Разделение каналов 117 дБ
  • Диапазон регулировки громкости от -120 до 0 дБ (программно ограничен от -50 до 0 дБ)
  • Фильтры:
    • Digital De-Emphasis (OFF, 32,0 44,1 48,0 кГц ) (программно поддерживается)
    • Digital Filter Rolloff: Sharp or Slow (программно поддерживается)
  • Soft Mute (программно поддерживается)
  • Zero Flag for Each Output (программно поддерживается)
  • Управление: SPI

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

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

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

Выше показана схема ресивера на CS8416, он имеет один активный вход, но можно использовать все 4-е доступные входы. Коммутация входами осуществляется при помощи пинов RSEL1 и RSEL0 микросхемы ресивера , при этом лог. 1 подается с питания VL (+5 В), а логический ноль с DGND.

INPUT RSEL0 RSEL1
RXP0 0 0
RXP1 1 0
RXP2 0 1
RXP3 1 1

Ресивер работает независимо от Arduino, в схеме присутствует индикатор режима работы светодиод D1, при подключении коаксиального кабеля с источником цифрового сигнала светодиод гаснет, при отключении кабеля загорается.

Схема ЦАП на PCM1796

Схема ФНЧ на NE5532

Блок управления на Arduino Nano

Регулировка громкости в диапазоне от -50 до 0 дБ осуществляется при помощи энкодера KY-040, нажатие кнопки энкодера переключает пункты меню, в первом меню находятся настройка уровня громкости, а так же выводятся данные о состоянии фильтров, второе меню отвечает за фильтр De-Emphasis, третье за фильтр Rolloff. Дополнительно в блоке управления используется кнопка для активации режима MUTE.

Схема стабилизаторов питания

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

Упрощенная схема стабилизаторов

#define MS      6   //  PCM1796
#define MDI     5   //  PCM1796
#define MC      4   //  PCM1796  
#define MDO     3   //  PCM1796
#define RST     2   //  PCM1796
#define CLK     9   //  ENCODER 
#define DT      8   //  ENCODER 
#define SW     10   //  ENCODER 
#define MUTE    7   //  BUTTON MUTE
// LCD1602 - I2C | A4=SDA A5=SCL
 
#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(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,times1,oldPosition  = -999,newPosition;
    int menu,w,w2,vol,mute,a[3],dem,roll,zero;
    byte i,d1,d2,d3,d4,d5,d6,e1,e2,e3;
 
void setup() {
  Serial.begin(9600);MsTimer2::set(1, to_Timer);MsTimer2::start();
  pinMode(RST,OUTPUT);
  pinMode(MDI,OUTPUT);
  pinMode(MC,OUTPUT);
  pinMode(MS,OUTPUT);
  pinMode(MDO,INPUT);
  pinMode(SW,INPUT);
  pinMode(MUTE,INPUT_PULLUP);
  digitalWrite(RST,LOW);digitalWrite(MC,LOW);digitalWrite(MS,HIGH);
  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);
  lcd.setCursor(5,0);lcd.print("CS 8416");
  lcd.setCursor(5,1);lcd.print("PCM1796");
  delay(1000);lcd.clear(); 
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении 
  vol = EEPROM.read(0);dem = EEPROM.read(1);roll = EEPROM.read(2); 
  digitalWrite(RST,HIGH);                
  audio();
}
 
void loop() {
 /// MENU //////////////////////////////
  if(digitalRead(SW)==LOW){menu++;if(menu>2){menu=0;};delay(200);lcd.clear();w=1;times=millis();w2=1;}
 /// MUTE ///////////////////
 if(digitalRead(MUTE)==LOW&&mute==0){mute=1;audio();delay(200);}
 if(digitalRead(MUTE)==LOW&&mute==1){mute=0;audio();delay(200);}  
 
 /// 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>99){vol=99;}if(vol<0){vol=0;}
     audio();}
 
      lcd.setCursor(0,0);
      if(mute==1){lcd.print("MUTE    ");}
      if(mute==0&&zero>0){lcd.print("No Sound");}
      if(mute==0&&zero==0){lcd.print("VOLUME  ");}  
      lcd.setCursor(0,1);
      switch(roll){
        case 0: lcd.print("SH ");break;
        case 1: lcd.print("SL ");break;
  }
      switch(dem){
        case 0: lcd.print("OFF ");break;
        case 1: lcd.print("48.0");break;
        case 2: lcd.print("44.1");break;
        case 3: lcd.print("32.0");break;
  }
 
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;}
      audio();}
 
  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("48.0 kHz      ");break;
    case 2: lcd.print("44.1 kHz      ");break;
    case 3: lcd.print("32.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;}
     audio();}
 
  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;
  }}}   
 
 //// EEPROM ///////////////////////////////////////
 if(millis()-times>5000 && w==1){w=0;EEPROM.update(0,vol);EEPROM.update(1,dem);EEPROM.update(2,roll);menu=0;lcd.clear();w2=1;}
 delay(100);
 
 /// READ REGISTER
 if(millis()-times1>1000){
 zero=ReadPCM1796(0b10010110); 
 Serial.print("Zero-Detection Flag ");Serial.println(zero,BIN);           // REG_22 |  Zero-Detection Flag
 Serial.print("Device ID ");Serial.println(ReadPCM1796(0b10010111),BIN);  // REG_23 |  Device ID
 Serial.println();times1=millis();}
}
 
void to_Timer(){newPosition = myEnc.read()/4;}
void audio(){
  WritePCM1796(0b00010000, vol+156);                        // REG_16
  WritePCM1796(0b00010001, vol+156);                        // REG_17
  WritePCM1796(0b00010010, 0b11010010 + mute + (dem << 2)); // REG_18
  WritePCM1796(0b00010011, 0b00000000 + (roll << 1));       // REG_19
  WritePCM1796(0b00010100, 0b00000000);                     // REG_20
  WritePCM1796(0b00010101, 0b00000001);                     // REG_21
  }
void WritePCM1796(byte reg, byte mdi){  // WRITE_REG 
   digitalWrite(MC,LOW);digitalWrite(MS,LOW);
     for(int i = 7; i >= 0; i--){
        digitalWrite(MC,LOW);
        digitalWrite(MDI, (reg >> i) & 0x01);
        digitalWrite(MC,HIGH);
        }
     for(int i = 7; i >= 0; i--){
        digitalWrite(MC,LOW);
        digitalWrite(MDI, (mdi >> i) & 0x01);
        digitalWrite(MC,HIGH);
        }
    digitalWrite(MC,LOW);digitalWrite(MS,HIGH);delay(1);
  }  
 
byte ReadPCM1796(byte reg){   // READ_REG  
  byte dat[8],data = 0;
  digitalWrite(MC,LOW);digitalWrite(MS,LOW);
     for(int i = 7; i >= 0; i--){
        digitalWrite(MC,LOW);
        digitalWrite(MDI, (reg >> i) & 0x01);
        digitalWrite(MC,HIGH);
        }
     for(int i = 7; i >= 0; i--){
        digitalWrite(MC,LOW);
        dat[i] = digitalRead(MDO);
        data = data + (dat[i] << i);
        digitalWrite(MC,HIGH);
        } 
        digitalWrite(MC,LOW);digitalWrite(MS,HIGH);delay(1);
    return data;
  }      

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

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

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

  • УМЗЧ на микросхеме TDA1552Q

    УМЗЧ на микросхеме TDA1552Q

    Усилитель при высоком качестве звучания очень прост в изготовлении и не нуждается в налаживании. Он имеет универсальный вход с плавной регулировкой чувствительности. Это практически «полный» усилитель, но без входов для микрофона и звукоснимателя. Усилитель мощности реализован на МС фирмы Philips TDA1552Q. Схема его включения позаимствована из [1]. Предварительный усилитель собран …Подробнее...
  • 2,1 — Dual усилитель мощности на TDA7240 и TDA1517

    2,1 — Dual усилитель мощности на TDA7240 и TDA1517

    Основная проблема с конструкцией усилителя с общим буфером , является то, что сигналы левого и правого каналов, рано или поздно суммируются. В результате простого сложения, разделение между каналами сводится к минимуму и нарушается сама идея stereofonii. Наиболее эффективным методом суммирования известный сегодня — сигнал активной smesitelyami — фильтры с высоким …Подробнее...
  • УМЗЧ 2*14Вт на TDA7269A

    УМЗЧ 2*14Вт на TDA7269A

    УМЗЧ на базе TDA7269A относится к классу АВ и предназначен для использования в усилителях Hi-Fi класса. Микросхема имеет тепловую защиту, защиту от КЗ выходов на корпус и шину питания. В микросхеме встроены функции MUTE и STAND-BY. Усилитель на базе TDA7269A имеет следующие технические характеристики: Номинальное напряжение питания +/-16В Напряжение питания …Подробнее...
  • РЕГУЛЯТОР ОБОРОТОВ ДЛЯ ЭЛЕКТРОИНСТРУМЕНТА

    РЕГУЛЯТОР ОБОРОТОВ ДЛЯ ЭЛЕКТРОИНСТРУМЕНТА

    На рисунке показана схема регулятора оборотов электроинструмента. При работе с электроинструментом желательно иметь возможность плавно изменять его обороты, но простое снижение напряжения приводит к снижению оборотов и так же к потери мощности, предложенная схема лишена этого недостатка, так как в ней используется регулирование с обратной связью по току двигателя, в …Подробнее...
  • Зарядное уст-во на TL497

    На рисунке показана схема зарядного уст-ва на основе преобразователя напряжения на ИС TL497. В схеме VR1 регулирует выходное напряжение. Преобразователь работает на частоте 50кГц и С3 задает эту частоту. Схема работает от напряжения 5В при токе источника (маломощный трансформатор с выпрямителем или солнечная панель) 100мА. Так же схема может работать …Подробнее...