Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Нужна помощь с кодеком TLV320AIC12K
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > PIC
dj_miles
Здравствуйте! Помогите разобраться с данным кодеком!!! В частности не получается конфигурировать его. Кодеком управляет PIC-контроллер по I2C интерфейсу, а тактируется от внутреннего генератора PIC'а 16 мГц. Сам же кодек юзаю в slave - режиме. Проблема заключается в записи регистров. Чтение проходит на ура, если читать по одному регистру. Прочитать все регистры разом не получается. Алгоритм чтения и записи выполняю точно так как описано в даташите. Что не так? Может кто то имел дело с данным чудом!!!!
Jury093
Цитата(dj_miles @ Feb 24 2014, 14:49) *
Что не так? Может кто то имел дело с данным чудом!!!!

всегда удивлялся таким вопросам - исходной информации ноль, кроме "не работает"..
где схема включения, где линк на даташит, где куски исходного кода, где лог с точкой неисправности?
железки все типовые, протоколы тоже.. и если нет патологии конкретного кристалла и все сделано верно, то и работать должно, как задумано производителем..

если электрически все соединено правильно, то вероятно у вас ошибка в реализации протокола обмена.. может бит готовности не опрашиваете, может подтверждения транзакции не проверяете, может чип не поддерживает групповые операции чтения/записи..
dj_miles
Спасибо за поправки!!!

Даташит на TLV320AIC12K TLV320AIK12, схема в файле.

Коды функций работы с I2C:

void IIC_STR() { I2C2CONbits.SEN = 1; while (I2C2CONbits.SEN); }
void IIC_RST() { I2C2CONbits.RSEN = 1; while (I2C2CONbits.RSEN); }
void IIC_STP() { I2C2CONbits.PEN = 1; while (I2C2CONbits.PEN);}
void IIC_WTX(unsigned char data){I2C2TRN = data; while (I2C2STATbits.TRSTAT == 1); while (I2C2STATbits.TBF == 1);}
unsigned char IIC_WRX() { I2C2CONbits.RCEN = 1; while (I2C2CONbits.RCEN);I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN); I2C2STATbits.I2COV = 0; return I2C2RCV;}
void IIC_IDL(){ while(I2C2CONbits.SEN || I2C2CONbits.RSEN || I2C2CONbits.PEN || I2C2CONbits.RCEN || I2C2CONbits.ACKEN || I2C2STATbits.TRSTAT);}
void IIC_ACK() { I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN);}

void I2C_Write(unsigned char add, unsigned char byte)
{
IIC_IDL();
IIC_STR();
IIC_WTX(0x80);
IIC_WTX(add);
IIC_STP();
IIC_IDL();
IIC_STR();
IIC_WTX(0x80);
if (I2C2STATbits.ACKSTAT);
IIC_WTX(add);
if (I2C2STATbits.ACKSTAT);
IIC_WTX(byte);
if (I2C2STATbits.ACKSTAT);
IIC_STP();
}

unsigned char I2C_Read(unsigned char add)
{
unsigned char r = 0;
IIC_IDL();
IIC_STR();
IIC_WTX(0x80);
IIC_WTX(add);
IIC_STP();
IIC_STR();
IIC_WTX(0x81);
r = IIC_WRX();
IIC_STP();
return r;
}

Забыл коменты написать!

Коды функций работы с I2C:

void IIC_STR() { I2C2CONbits.SEN = 1; while (I2C2CONbits.SEN); }
void IIC_RST() { I2C2CONbits.RSEN = 1; while (I2C2CONbits.RSEN); }
void IIC_STP() { I2C2CONbits.PEN = 1; while (I2C2CONbits.PEN);}
void IIC_WTX(unsigned char data){I2C2TRN = data; while (I2C2STATbits.TRSTAT == 1); while (I2C2STATbits.TBF == 1);}
unsigned char IIC_WRX() { I2C2CONbits.RCEN = 1; while (I2C2CONbits.RCEN);I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN); I2C2STATbits.I2COV = 0; return I2C2RCV;}
void IIC_IDL(){ while(I2C2CONbits.SEN || I2C2CONbits.RSEN || I2C2CONbits.PEN || I2C2CONbits.RCEN || I2C2CONbits.ACKEN || I2C2STATbits.TRSTAT);}
void IIC_ACK() { I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN);}

void I2C_Write(unsigned char add, unsigned char byte)
{
IIC_IDL(); //Ожидаем освобождения модуля I2C
IIC_STR(); // Последовательность старт-бита
IIC_WTX(0x80);//Адрес слейва с признаком записи
if (I2C2STATbits.ACKSTAT); //Проверка подтверждения
IIC_WTX(add); //Адрес регистра
if (I2C2STATbits.ACKSTAT);
IIC_WTX(byte); //Значение регистра
if (I2C2STATbits.ACKSTAT);
IIC_STP();//Стоп-бит
}

unsigned char I2C_Read(unsigned char add)
{
unsigned char r = 0;
//Запись индекса регистра
IIC_IDL(); //Ожидаем освобождения модуля I2C
IIC_STR();// Последовательность старт-бита
IIC_WTX(0x80);//Адрес слейва с признаком записи
IIC_WTX(add); //Адрес регистра
IIC_STP(); //Стоп-бит

IIC_STR(); //Старт-бит
IIC_WTX(0x81); //Адрес слейва с признаком чтения
r = IIC_WRX(); //Чтение
IIC_STP(); //Стоп-бит
return r;
}
Jury093
Цитата(dj_miles @ Feb 25 2014, 14:04) *
Спасибо за поправки!!!

ну вот так заметно лучше..
по электросхеме - использована шина i2c, а где подтяжки (pullup)? шина с ОК и должны стоять резисторы от контактов scl и sda на +3в3 (в диапазоне 4к7..10к)
dj_miles
Цитата(Jury093 @ Feb 25 2014, 14:37) *
ну вот так заметно лучше..
по электросхеме - использована шина i2c, а где подтяжки (pullup)? шина с ОК и должны стоять резисторы от контактов scl и sda на +3в3 (в диапазоне 4к7..10к)



На схеме не указаны, но на самом деле стоят. По поводу номиналов: я так понимаю, что он выбирается в зависимости огт скорости? У меня сейчас стоят 1к.
Jury093
Цитата(dj_miles @ Feb 25 2014, 15:43) *
На схеме не указаны, но на самом деле стоят. По поводу номиналов: я так понимаю, что он выбирается в зависимости огт скорости? У меня сейчас стоят 1к.

понятно, 1к в принципе не криминал, раз чтение работает, то сгодится..

по исходникам (по счастью я Пиками не работал) - визуально не хватает в п/п чтения таких строчек (это из п/п записи)
Код
if (I2C2STATbits.ACKSTAT); //Проверка подтверждения


я очень давно не возился с отладкой i2c, но по протоколу на каждое обращение к чипу должен прийти Ask (который может отсутствовать при передачи нескольких байт в блоке)..

на всякий случай - по вышеприведенной ссылке не даташит, а "TLV320AIC12/13/14/15 Codec Operating In Stand-Alone Slave Mode"
даташит лежит рядом - www.ti.com/cn/lit/gpn/tlv320aic12k
dj_miles
Короче сделал щас так: перевел его в режим мастера и все как по маслу работает. Вот теперь вопрос: почему он в слейв режиме не хотел записывать значения регистров?!!! Остается загадкой! Так ведь судя по всему касаясь шины I2C, он ведь так и остался в слейв режиме!

По поводу подтверждения: согласен! Указанный флаг просто не учитывается у меня, но по факту читается бы ло ли подтверждение от слейва.
dj_miles
Выкладываю свой тестовый проект, может кому понадобиться. Камень PIC24FJ64GA004. Среда MPLAB IDE. Компилятор XC16.

В кратце опишу: TLV320 работает в Master-режиме, так как в slave добиться нормальной и стабильной работы так и не удалось, да и работать как оказалось в этом режиме очень удобно. Возможно это связано с процедурой сброса. Частота тактирования кодека взята с PIC, с выхода частоты переферии( у меня внутренний генератор с PLL 32 мГц, выход на лапе 16 мГц). В проекте есть файл ded.h - это тестовый кусочек для воспроизведения. Для теста микрофонного входа можно соеденить сигнал SPI_DIN_1 и SPI_DOUT_1, тогда все , что вы говорите в микрофон можно сразу услышать в динамике.

В целом кодек не плохой. Мощности для динамика маловато или может, что то с конфигурацией намудрил. А так качество вполне неплохое.

Будут вопросы, с удовольствием отвечу!
Россиянин
Цитата(dj_miles @ Feb 25 2014, 11:04) *
Спасибо за поправки!!!

Даташит на TLV320AIC12K TLV320AIK12, схема в файле.

Коды функций работы с I2C:

void IIC_STR() { I2C2CONbits.SEN = 1; while (I2C2CONbits.SEN); }
void IIC_RST() { I2C2CONbits.RSEN = 1; while (I2C2CONbits.RSEN); }
void IIC_STP() { I2C2CONbits.PEN = 1; while (I2C2CONbits.PEN);}
void IIC_WTX(unsigned char data){I2C2TRN = data; while (I2C2STATbits.TRSTAT == 1); while (I2C2STATbits.TBF == 1);}
unsigned char IIC_WRX() { I2C2CONbits.RCEN = 1; while (I2C2CONbits.RCEN);I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN); I2C2STATbits.I2COV = 0; return I2C2RCV;}
void IIC_IDL(){ while(I2C2CONbits.SEN || I2C2CONbits.RSEN || I2C2CONbits.PEN || I2C2CONbits.RCEN || I2C2CONbits.ACKEN || I2C2STATbits.TRSTAT);}
void IIC_ACK() { I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN);}

void I2C_Write(unsigned char add, unsigned char byte)
{
IIC_IDL();
IIC_STR();
IIC_WTX(0x80);
IIC_WTX(add);
IIC_STP();
IIC_IDL();
IIC_STR();
IIC_WTX(0x80);
if (I2C2STATbits.ACKSTAT);
IIC_WTX(add);
if (I2C2STATbits.ACKSTAT);
IIC_WTX(byte);
if (I2C2STATbits.ACKSTAT);
IIC_STP();
}

unsigned char I2C_Read(unsigned char add)
{
unsigned char r = 0;
IIC_IDL();
IIC_STR();
IIC_WTX(0x80);
IIC_WTX(add);
IIC_STP();
IIC_STR();
IIC_WTX(0x81);
r = IIC_WRX();
IIC_STP();
return r;
}

Забыл коменты написать!

Коды функций работы с I2C:

void IIC_STR() { I2C2CONbits.SEN = 1; while (I2C2CONbits.SEN); }
void IIC_RST() { I2C2CONbits.RSEN = 1; while (I2C2CONbits.RSEN); }
void IIC_STP() { I2C2CONbits.PEN = 1; while (I2C2CONbits.PEN);}
void IIC_WTX(unsigned char data){I2C2TRN = data; while (I2C2STATbits.TRSTAT == 1); while (I2C2STATbits.TBF == 1);}
unsigned char IIC_WRX() { I2C2CONbits.RCEN = 1; while (I2C2CONbits.RCEN);I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN); I2C2STATbits.I2COV = 0; return I2C2RCV;}
void IIC_IDL(){ while(I2C2CONbits.SEN || I2C2CONbits.RSEN || I2C2CONbits.PEN || I2C2CONbits.RCEN || I2C2CONbits.ACKEN || I2C2STATbits.TRSTAT);}
void IIC_ACK() { I2C2CONbits.ACKEN = 1; while (I2C2CONbits.ACKEN);}

void I2C_Write(unsigned char add, unsigned char byte)
{
IIC_IDL(); //Ожидаем освобождения модуля I2C
IIC_STR(); // Последовательность старт-бита
IIC_WTX(0x80);//Адрес слейва с признаком записи
if (I2C2STATbits.ACKSTAT); //Проверка подтверждения
IIC_WTX(add); //Адрес регистра
if (I2C2STATbits.ACKSTAT);
IIC_WTX(byte); //Значение регистра
if (I2C2STATbits.ACKSTAT);
IIC_STP();//Стоп-бит
}

unsigned char I2C_Read(unsigned char add)
{
unsigned char r = 0;
//Запись индекса регистра
IIC_IDL(); //Ожидаем освобождения модуля I2C
IIC_STR();// Последовательность старт-бита
IIC_WTX(0x80);//Адрес слейва с признаком записи
IIC_WTX(add); //Адрес регистра
IIC_STP(); //Стоп-бит

IIC_STR(); //Старт-бит
IIC_WTX(0x81); //Адрес слейва с признаком чтения
r = IIC_WRX(); //Чтение
IIC_STP(); //Стоп-бит
return r;
}

В Протеусе нарисована схма? В в версии 8.0 TLV320 не нашёл.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.