Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: PIC24JF64GA002 проблема с I2Cx
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > PIC
PoroHard
Подскажите пожалуста!

I2C2BRG = 78;
I2C2CON = 0xD200;

while (I2C2STATbits.TRSTAT); //Wait for bus Idle

I2C2CONbits.SEN = 1; //Generate Start COndition
while (I2C2CONbits.SEN); //Wait for Start COndition

После установки бита SEN на шынах SDAx, SCLx не выставляется занятие шыны.
I2C не работает.
Проблема одинаковая для I2C1 и I2C2.
evc
SDA и SCL пины должны быть настрены на вход. И лучше оставьте I2CxCONbits.14 в 0!
PoroHard
Цитата(evc @ May 9 2008, 13:37) *
SDA и SCL пины должны быть настрены на вход. И лучше оставьте I2CxCONbits.14 в 0!


Благодарю за ответ.

Настроил SDA и SCL пины на вход, установил I2CxCONbits.14 в 0.
Результат прежний.
В пошаговом режиме после установки бита SEN пины в 0 не устанавливаются.

Тактирование от внутреннего генератора 8мГЦ.
Пробовал менять чип, результат прежний.

прилагаю исходник
int main(woid)
{
ControlByte = 0x3C <<1;
TRISB = 0xffff;
/
I2C2BRG = 78;
I2C2CON = 0x9200; //Enable While PB9 is low
I2C2ADD=0;
I2C2MSK=0;
while(1)
{
while (I2C2STATbits.TRSTAT); //Wait for bus Idle
I2C2CONbits.SEN = 1; //Generate Start COndition
while (I2C2CONbits.SEN); //Wait for Start COndition
//(В пошаговом режиме после установки бита SEN пины в 0 не устанавливаются.)
while (I2C2STATbits.TRSTAT); //Wait for bus Idle
I2C2TRN = ControlByte; //Load byte to I2C1 Transmit buffer
while (I2C2STATbits.TBF); //wait for data transmission
while (I2C2STATbits.TRSTAT); //Wait for bus Idle
I2C2TRN = 0x80; //Load byte to I2C1 Transmit buffer
while (I2C2STATbits.TBF); //wait for data transmission
while (I2C2STATbits.TRSTAT); //Wait for bus Idle
I2C2CONbits.PEN = 1; //Generate Stop Condition
while (I2C2CONbits.PEN); //Wait for Stop
for(i=0; i<10; i++);
}
return 0;
}
viael
Цитата(PoroHard @ May 9 2008, 13:57) *
Подскажите пожалуста!

I2C2BRG = 78;
I2C2CON = 0xD200;

while (I2C2STATbits.TRSTAT); //Wait for bus Idle

I2C2CONbits.SEN = 1; //Generate Start COndition
while (I2C2CONbits.SEN); //Wait for Start COndition

После установки бита SEN на шынах SDAx, SCLx не выставляется занятие шыны.
I2C не работает.
Проблема одинаковая для I2C1 и I2C2.


Эррату на камень читал?

detected properly unless it is first held low for
150 ns after enabling the I2C module.
In Master mode, this error may cause a bus collision
to occur instead of a Start bit transmission.
Transmissions after the SDA1 pin has been held
low will occur correctly.

Я тоже по этим граблям ходил.Никакие воркэраунды не помогли.В итоге сделал софтварную реализачию.
PoroHard
Цитата(viael @ May 9 2008, 17:31) *
Эррату на камень читал?

detected properly unless it is first held low for
150 ns after enabling the I2C module.
In Master mode, this error may cause a bus collision
to occur instead of a Start bit transmission.
Transmissions after the SDA1 pin has been held
low will occur correctly.

Я тоже по этим граблям ходил.Никакие воркэраунды не помогли.В итоге сделал софтварную реализачию.


Добрый день!
Эрату я читал, но решил что это касается только I2C1.
Софтовая реализация мне не подходит.
Ilya_A
У меня с такими процедурами все работает нормально (I2C2):

Код
void InitI2C(void){    
      I2C2CON=0;  
    I2C2BRG = 0x0013;
    I2C2STAT = 0x0000;
    I2C2CON = 0x1200;
    I2C2RCV = 0x0000;
    I2C2TRN = 0x0000;
    I2C2CON = 0x9200;
    IdleI2C();    
}
void StartI2C(void){
    I2C2CONbits.SEN = 1;        
    while (I2C2CONbits.SEN);    
}
void StopI2C(void)
{
    I2C2CONbits.PEN = 1;        
    while (I2C2CONbits.PEN);    
}

void WrI2C(unsigned char byte)
{
    I2C2TRN = byte;                    
    while (I2C2STATbits.TBF);        
    IdleI2C();
}
unsigned char RdI2C(unsigned char ack)
{
    I2C2CONbits.RCEN=1;
    while (I2C2CONbits.RCEN==1);        
    AckI2C(ack);
    return I2C2RCV;
}
void IdleI2C(void)
{
    while (I2C2STATbits.TRSTAT);        
}
unsigned char ACKStatus(void)
{
    return (!I2C2STATbits.ACKSTAT);    
}
void AckI2C(unsigned char ack){
    I2C2CONbits.ACKDT = !ack;        
    I2C2CONbits.ACKEN = 1;
    while(I2C2CONbits.ACKEN);        
    I2C2CONbits.ACKDT = 0;        
}


ЗЫ: Подтяжки по 4,7К; порты настроены на вход;
PoroHard
Доброе утро Илья.

Благодарю за ваш ответ.
Вчера мне удалось запустить I2C2, a затем I2C1. Но только путём подключения RB10 к линии SDA
и её передёргиванием после установки бита SEN.
Установка линий на вхов результатов не давала.

int main(woid)
{
ControlByte = 0x3C <<1;
TRISB = 0;
TRISB &= ~LCD_RESET;
PORTB &= ~LCD_RESET;
for(i=0; i<1000; i++);
PORTB |= LCD_RESET;
for(i=0; i<100; i++);

ODCB = 0x0400;
PORTB |= 0x0400;

I2C1BRG = 18;
I2C1CON = 0x9200;
I2C1ADD=0;
I2C1MSK=0;

PORTB &= ~0x0400;
PORTB |= 0x0400;

pBuff = init_lcd;
while (I2C1STATbits.TRSTAT); //Wait for bus Idle
I2C1CONbits.SEN = 1; //Generate Start COndition
while (I2C1CONbits.SEN); //Wait for Start COndition
while (I2C1STATbits.TRSTAT); //Wait for bus Idle
I2C1TRN = ControlByte; //Load byte to I2C1 Transmit buffer
while (I2C1STATbits.TBF); //wait for data transmission
for(i=0; i<sizeof(init_lcd); i++)
{
while (I2C1STATbits.TRSTAT); //Wait for bus Idle
I2C1TRN = *pBuff++; //Load byte to I2C1 Transmit buffer
while (I2C1STATbits.TBF); //wait for data transmission
}
while (I2C1STATbits.TRSTAT); //Wait for bus Idle
I2C1CONbits.PEN = 1; //Generate Stop Condition
while (I2C1CONbits.PEN); //Wait for Stop
}

Вечером переключю LCD на I2C2 и сообщю о результате.

С уважением PoroHard.
evc
Цитата(PoroHard @ May 12 2008, 10:05) *
...
pBuff = init_lcd;
while (I2C1STATbits.TRSTAT); //Wait for bus Idle
I2C1CONbits.SEN = 1; //Generate Start COndition
while (I2C1CONbits.SEN); //Wait for Start COndition
while (I2C1STATbits.TRSTAT); //Wait for bus Idle
I2C1TRN = ControlByte; //Load byte to I2C1 Transmit buffer
while (I2C1STATbits.TBF); //wait for data transmission
??? REstart condition ???
for(i=0; i<sizeof(init_lcd); i++)
{
while (I2C1STATbits.TRSTAT); //Wait for bus Idle
I2C1TRN = *pBuff++; //Load byte to I2C1 Transmit buffer
while (I2C1STATbits.TBF); //wait for data transmission
}
while (I2C1STATbits.TRSTAT); //Wait for bus Idle
I2C1CONbits.PEN = 1; //Generate Stop Condition
while (I2C1CONbits.PEN); //Wait for Stop
}

Вечером переключю LCD на I2C2 и сообщю о результате.

С уважением PoroHard.


Извините, но вы вообще читали спецификацию I2C? biggrin.gif "Idle" - это означает что шина свободная, и scl и sda в "1". После старта, она занята - и sda и scl - "0". Достигнув ту строчку, которой я выделил красным цветом ("Wait for bus Idle") ваша программа зависнеть на смерть (или на watchdog, если он, конечно, работает). "Wait for Start COndition" тоже можете убрать.
И еще:
Не знаю какой у вас LCD, но протокол I2C обмена обычно требует сначала адрес, потом контрольное слово, потом повторный старт ("restart condition"). И только после этого, можете начинать отправлять данные...
Цитата(PoroHard @ May 12 2008, 10:05) *
Установка линий на вхов результатов не давала.

Потому что вы, наверно, внешные пулл-апы (подтяжки к "+") на SCL и SDA, тоже не поставили ... smile.gif
PoroHard
Цитата(evc @ May 12 2008, 16:16) *
Извините, но вы вообще читали спецификацию I2C? biggrin.gif "Idle" - это означает что шина свободная, и scl и sda в "1". После старта, она занята - и sda и scl - "0". Достигнув ту строчку, которой я выделил красным цветом ("Wait for bus Idle") ваша программа зависнеть на смерть (или на watchdog, если он, конечно, работает). "Wait for Start COndition" тоже можете убрать.
И еще:
Не знаю какой у вас LCD, но протокол I2C обмена обычно требует сначала адрес, потом контрольное слово, потом повторный старт ("restart condition"). И только после этого, можете начинать отправлять данные...

Потому что вы, наверно, внешные пулл-апы (подтяжки к "+") на SCL и SDA, тоже не поставили ... smile.gif


Резисторы 4к7 на +3.3 были установленны изначально.
LCD TIC32(chip PCF8531) имеет режим только записи, его адрес 0х3с(ControlByte = 0x3C <<1;).
init_lcd - стринг содержащий отлаженную последовательность команд и данных.
watchdog - отключен, программа независала.
При отключении "Wait for Start COndition" пример перестаёт работать.
Контроль за работой линий SCL и SDA производился цыфровым 500мГц осцылографом.
После установки бита SEN линии SCL и SDA в 0 неустанавливались.
evc
Цитата(PoroHard @ May 12 2008, 22:18) *
...LCD TIC32(chip PCF8531)...


Сдесь его хорошенко разжевали... (см. вложение)

В примере, который в pdf привели, тоже пользуется "i2c_wait_idle", но в ней ожидается не освобождение шины, а завершение всех действий со стороны процессора:

Код
void i2c_wait_idle(void){
    while((I2C1CON&0x001F) || I2C1STATbits.TBF);
    delay_us(10);
}
PoroHard
Содержимое ссылки я смотрел рание. До подключения индикатора к PIC24 он был подключен к BLACKFIN BF548, написан и отлажен знакогенератор и вывод текста(графики) на экран.
Проблема состаит не в инициализации(управлении,отображении) LCD, а в том, что не активируется
сам I2C(картина одинаковая для 1 и 2 интерфейса).
Только внешнее "передёргивание" приводит к активации 1-го или 2-го интерфейса.

На I2C2 пример Ильи не заработал.

Работаю с PIC24FJ64GA002 (Rev 0x3003). Возмижно для IC24FJ64GA004 ситуация другая.
mih@lych
у когонибудь заработал I2C на PIC24FJ64GA002 ???
mih@lych
Незнаю как у кого, но Errata не помогла, заработал только после того, как руками дёрнул...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.