Потихоньку разгребаюсь от неинтересных дел, решил приступить к ковырянию TDA8425. Ведь именно с помощью ее я собираюсь рулить моим будущим усилителем 🙂
Таак, сначала как обычно лезем в даташит и внимательно все читаем: Данный процессор (он же предусилитель) позволяет:
- Регулировать громкость в пределах -64..6 дБ
- Регулировать бас в пределах -15..12 дБ
- Регулировать тембр в пределах -12..12 дБ
- Имеет два раздельных входа, которые можно переключать цифровым путем
- Может переключать режимы с этих входов (моно, стерео, псевдостерео)
- Напряжение высокого логического уровня можно варьировать в пределах 3..Vcc В (что весьма кстати с учетом того, что питается чип от 12 вольт)
Я решил, что сначала надо определиться с командами и функциями, поэтому сейчас будет немного скучных цифр и букв кода 🙂 Передача по i2c на tda8425 всегда должна начинаться с первого адреса – байта, он же число 82h. Вторым байтом идет субадрес (это они его так в даташите обзывают), здесь уже есть некоторая функциональность:
- Максимальное усиление 6 дБ, что соответствует значению 63 в десятичной системе.
- Чтобы определить нужное значение используем формулу: Xdec = 63 – (6-Gain)/2

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(); } } }
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); //И возвращаем его для последующих операций }
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. Если кто-то читает всю эту мою ересь и кому-то она даже интересна, большая просьба выключать адблок или другие блокираторы рекламы и пощелкать по ссылкам в контекстной рекламе (один из блоков есть в самом низу этой страницы), а мне за это пару копеек насыпят, буду пытаться окупать хостинг 🙂
Если последний абзац увидят модераторы этих самых рекламных баннеров – забанят и денег не дадут.
Интересная ересь 🙂
Вот был бы раздел с полезной литературой. Мне вот например, интересен самоучитель для PIC на С.
Вот так всё интересное в Минске происходит… Ай..
Ээ, да они сообственно тут и ни при чем по идее, я через google adsense набиваю по чутка, хочу хоть раз хостинг оплатить из заработанных в сети денег 🙂
Про раздел с литературой – сделать можно, только вот там скорее будут книжки по схемотехнике и программированию, а по PIC самоучителя я для себя хорошего так и не нашел. Изначально учил по английскому от mikroelectronika, а потом по примерам и даташитам повторял.
ps. В Беларуси с электроникой везде туго, в том числе и в минске, ну может в нем слегка попроще чем в других городах, но один фиг *опа мира 🙂
Я могу порекомендовать книгу Катцен С. – PIC микроконтроллеры. Всё, что Вам необходимо знать. Лучше, в свое время, ничего не нашел.
Я ее по диагонали когда то пробежал. Мне не понравилось, что там слишком много внимания уделяется основам цифровой электроники.
А почему адрес процессора 82h? По датышу B10000010 а это либо 130 либо 65 если B1000001 без R/W
А сейчас переведите 130 в шестнадцатиричную систему счисления. 😉
все вопросов нет)))
Спасибо автору! Респекс!! Спасибо ещё за все остальные статьи!
Работает даже с моей корявенькой библиотекой I2C))
А вам спасибо за отзыв 🙂
Вам ещё больше спасибо))
как с вами связаться,есть больная тема по похожему проекту ищу спеца для консультации,буду благодарен если откликнитесь
email – sargein@gmail.com
skype – sargein
Единственное – не обещаю, что буду отвечать быстро.
Уведомление: Усилитель с мозгами на tda7294 | PIC микроконтроллеры