Аудиопроцессор TDA8425 для проекта усилителя на TDA7294

Потихоньку разгребаюсь от неинтересных дел, решил приступить к ковырянию TDA8425. Ведь именно с помощью ее я собираюсь рулить моим будущим усилителем :)

Таак, сначала как обычно лезем в даташит и внимательно все читаем: Данный процессор (он же предусилитель) позволяет:

  • Регулировать громкость в пределах -64..6 дБ
  • Регулировать бас в пределах -15..12 дБ
  • Регулировать тембр в пределах -12..12 дБ
  • Имеет два раздельных входа, которые можно переключать цифровым путем
  • Может переключать режимы с этих входов (моно, стерео, псевдостерео)
  • Напряжение высокого логического уровня можно варьировать в пределах 3..Vcc В (что весьма кстати с учетом того, что питается чип от 12 вольт)

Я решил, что сначала надо определиться с командами и функциями, поэтому сейчас будет немного скучных цифр и букв кода :) Передача по i2c на tda8425 всегда должна начинаться с первого адреса – байта, он же число 82h. Вторым байтом идет субадрес (это они его так в даташите обзывают), здесь уже есть некоторая функциональность:

0h – громкость левого канала
1h – громкость правого канала
2h – бас
3h – тембр
8h – функции переключений
Третий финальный байт является уже непосредственно командным, в нем мы и заносим наши значения. С ним нужно быть осторожным, т.к. в зависимости от предназначения у него может быть замороженным разное количество старших бит:
Таблицы истинности для всех значений можно найти опять же в даташите, тут я их подробно приводить не буду. Остановлюсь пожалуй только на громкости, так как при первом рассмотрении меня их таблица истинности поставила в ступор:
Я привык, что мне все подробно расписывают в даташите, и если ничего не указано иного, то жду что счет будет идти от большего к меньшему линейно, но тут как ни крути линейности по цифрам не видать. Хорошо, что есть форумы по электронике с умными людьми :) Логика здесь следующая:
  • Максимальное усиление 6 дБ, что соответствует значению 63 в десятичной системе.
  • Чтобы определить нужное значение используем формулу: Xdec = 63 – (6-Gain)/2
Update: Я сейчас по просьбе одного человека просматривал основы работы с этой микрухой и просто в упор не понимаю как я не мог видеть логики в увеличении громкости? КАК? Блин все настолько просто – максимальное усиление есть 6 дБ = 255, дальше по убывающей в линейном режиме, и все блин!
Пример: Для значения -50 дБ, 63 – (6+50)/2 = 35 = 0b00100011, значит пишем значение 0b11100011 Ну вроде скользкие моменты все указал, перехожу к схеме. Схему берем полностью из даташита: Добавил от себя лишь проходной моп транзистор, которым можно будет регулировать подачу питания с помощью микроконтроллера.Вытравил платку, и взялся за код, с самого начала было решено выносить все функции в отдельный файл для безболезненного так сказать встраивания в другие проекты.
Переходим к коду, для начала функции громкости левого и правого каналов:
void VL(signed char VLbyte) //Громкость левого канала
{

if (VLbyte>6) VLbyte = 6;            //6 дБ наш максимум
if (VLbyte<-64) VLbyte = -80;        //-80 дБ наш минимум
if (VLbyte<-80) VLbyte = -80;

if (!(VLbyte%2))                    //если идем с шагом 2 дБ
 {
   if (VLbyte == -80)               //если -80
     {
      I2CStart();
      I2CSend(0x82);               //адрес тда8425
      I2CSend(0x00);               //байт выбора левого канала
      I2CSend(192 | 0);            //шлем нулевое значение
      I2CStop();
     } else
       {
         I2CStart();
         I2CSend(0x82);
         I2CSend(0x00);
         I2CSend(192 | (63 - (6-VLbyte)/2));  //иначе шлем по формуле
         I2CStop();
       }
 }//!VLbyte
}

Для правого канала точно также, ну за исключением командного байта на посыл в правый канал :) Формулы перевода вдолбил сразу, чтобы из главной программы не парится и передавать тупо значение усиления. От ошибочных значений я также перестраховался, если случайно попадет нечетное число то оно будет проигнорировано программой. Беремся за басы:


void BassSetup(signed char BassByte) //Установки басса - разрешенные значения от -12 до 15, шаг 3 дБ
{

if (BassByte > 15) BassByte = 15;            //максимум 15 дБ
if (BassByte < -12) BassByte = -12;          //минимум -12 дБ

if (!(BassByte%3))          //Если на три не делится, то нам прилетел какой-то шлак
{
 unsigned char temp;
 temp = 0;
 switch(BassByte)          //Разгребаем что нам прилетело
 {
       case 15 : temp = 11;
                 break;
       case 12 : temp = 10;
                 break;
       case 9 : temp = 9;
                break;
       case 6 : temp = 8;
                break;
       case 3 : temp = 7;
                break;
       case 0 : temp = 6;
                break;
       case -3 : temp = 5;
                 break;
       case -6 : temp = 4;
                 break;
       case -9 : temp = 3;
                 break;
       case -12 : temp = 2;
                  break;
 }//switch
if (temp)  //Если темп не в нуле, то что-то адекватное
{
 I2CStart();
 I2CSend(0x82);
 I2CSend(0x02);
 I2CSend(240 | temp);
 I2CStop();
}
}

}

Здесь уже по формуле забивать у меня не получилось, поэтому я просто организовал выбор по дискретным значения в разрешенном промежутке (-12 .. 15 дБ). Точно так же поступил и с тембром:


void TrebleSetup(signed char TrebleByte) //тембр от -12 до 12, шаг 3 дБ
{

if (TrebleByte < -12) TrebleByte = -12;
if (TrebleByte > 12) TrebleByte = 12;

if (!(TrebleByte%3)) //Если на три не делится, то нам прилетел какой-то шлак
 {
 unsigned char temp;
 temp = 0;
 switch(TrebleByte)
  {
     case 12 : temp = 10;
               break;
      case 9 : temp = 9;
               break;
      case 6 : temp = 8;
               break;
      case 3 : temp = 7;
               break;
      case 0 : temp = 6;
               break;
     case -3 : temp = 5;
               break;
     case -6 : temp = 4;
               break;
     case -9 : temp = 3;
               break;
    case -12 : temp = 2;
               break;
 } //switch
 if (temp) //Если темп не в нуле, то что-то адекватное
  {
    I2CStart();
    I2CSend(0x82);
    I2CSend(0x03);
    I2CSend(240 | temp);
    I2CStop();
  }

}
}
В проекте усилителя подразумевается что значения громкости, тембра, басов, а также переключаемых функций будут храниться в энергонезависимой памяти, причем очень важно не забывать записывать все значения при каждом включении питания аудиопроцессора иначе работать ничего не будет.
Для переключаемых функций у нас есть 5 бит, начнем с режима “Mute” :
unsigned char Mute(unsigned char SwByte, unsigned char MuteBit) // Mute, возвращает обновленное значение байта переключений
{
 SwByte &= 0b11011111;                        //Обнуляем бит mute в байте
 MuteBit <<= 5;                                        //сдвигаем нужное значение на правильную позицию

I2CStart();
 I2CSend(0x82);
 I2CSend(0x08);
 I2CSend(SwByte | MuteBit);                   //Шлем весь новый байт
 I2CStop();

return (SwByte | MuteBit);                      //И возвращаем его для последующих операций
}
Как видно в данном случае мы уже оперируем со всем байтом, а т.к. он не в одной функции используется, то функция возвращает его обновленное значение, которое можно в последствии записать в EEPROM.
Дальше выбор режима:
unsigned char ModeSel(unsigned char SwByte, unsigned char ModeByte)

{

/* 0 - моно
 1 - линейное стерео
 2 - псевдо стерео
 3 - пространственное стерео
*/
 SwByte &= 0b11100111;
 ModeByte <<= 3;
 I2CStart();
 I2CSend(0x82);
 I2CSend(0x08);
 I2CSend(SwByte | ModeByte);
 I2CStop();

return (SwByte | ModeByte);
}

Принцип тот же, что и у предыдущей функции – при вызове указываем значение всего байта переключаемых функций, а также байт нового режима. Кстати, из этих всех режимов мне больше всего понравилось “псевдо стерео”.
Ну и последнее – выбор источника:

unsigned char SourceSel(unsigned char SwByte, unsigned char SourceByte)
{
/* 2 - 1 канал sound A
 3 - 2 канал sound A
 4 - 1 канал sound B
 5 - 2 канал sound B
 6 - 1 канал стерео
 7 - 2 канал стерео
*/
 SwByte &= 0b11111000;
 I2CStart();
 I2CSend(0x82);
 I2CSend(0x08);
 I2CSend(SwByte | SourceByte);
 I2CStop();

return (SwByte | SourceByte);
}

Снова тот же принцип. Здесь хочу отметить, что разницы между всеми этими источниками я на мой слух никакой не заметил (естественно в пределах одного канала :)). Поэтому юзаю только 6 и 7 режим.

Собственно дело сделано, а как же проверять? Для этого я накидал программу с менюшкой под уарт. Вот примерно такую:

А вот здесь весь проект целиком в архиве.

Таким образом, все функции можно проверить через терминал, что я собственно и сделал в видео:

Качество не супер, все на телефон снято, но я пока без фотика так что лучше так чем вообще без всего.

P.S. Если кто-то читает всю эту мою ересь и кому-то она даже интересна, большая просьба выключать адблок или другие блокираторы рекламы и пощелкать по ссылкам в контекстной рекламе (один из блоков есть в самом низу этой страницы), а мне за это пару копеек насыпят, буду пытаться окупать хостинг :)

Аудиопроцессор TDA8425 для проекта усилителя на TDA7294: 12 комментариев

  1. Если последний абзац увидят модераторы этих самых рекламных баннеров – забанят и денег не дадут.

    Интересная ересь :)

    Вот был бы раздел с полезной литературой. Мне вот например, интересен самоучитель для PIC на С.

    Вот так всё интересное в Минске происходит… Ай..

    Ответить

  2. Ээ, да они сообственно тут и ни при чем по идее, я через google adsense набиваю по чутка, хочу хоть раз хостинг оплатить из заработанных в сети денег :)

    Про раздел с литературой – сделать можно, только вот там скорее будут книжки по схемотехнике и программированию, а по PIC самоучителя я для себя хорошего так и не нашел. Изначально учил по английскому от mikroelectronika, а потом по примерам и даташитам повторял.

    ps. В Беларуси с электроникой везде туго, в том числе и в минске, ну может в нем слегка попроще чем в других городах, но один фиг *опа мира :)

    Ответить

  3. Я могу порекомендовать книгу Катцен С. – PIC микроконтроллеры. Всё, что Вам необходимо знать. Лучше, в свое время, ничего не нашел.

    Ответить

  4. Я ее по диагонали когда то пробежал. Мне не понравилось, что там слишком много внимания уделяется основам цифровой электроники.

    Ответить

  5. А почему адрес процессора 82h? По датышу B10000010 а это либо 130 либо 65 если B1000001 без R/W

    Ответить

    sarge Ответил:

    А сейчас переведите 130 в шестнадцатиричную систему счисления. ;)

    Ответить

    Nik Ответил:

    все вопросов нет)))

    Ответить

  6. Спасибо автору! Респекс!! Спасибо ещё за все остальные статьи!

    Работает даже с моей корявенькой библиотекой I2C))

    Ответить

    sarge Ответил:

    А вам спасибо за отзыв :)

    Ответить

    Максим Наумчук Ответил:

    Вам ещё больше спасибо))

    Ответить

  7. как с вами связаться,есть больная тема по похожему проекту ищу спеца для консультации,буду благодарен если откликнитесь

    Ответить

    sarge Ответил:

    email – sargein@gmail.com
    skype – sargein

    Единственное – не обещаю, что буду отвечать быстро.

    Ответить

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">