реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Странности i2c
the_spirit
сообщение Jul 21 2012, 14:06
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 25-11-10
Из: Красногорск
Пользователь №: 61 170



Решил поисследовать i2c на предмет работы с длинными проводами. С проводами длиннее 10 м, если я не ошибаюсь, TWI не работает по спецификации. Поэтому эксперименты проводились с кабелем RC10 длиной 10м, Master-Atmega128, Slave-Atmega48. Результаты получились весьма странными. С подтягивающими резисторами на slave плате и на Master плате предельной частотой работы оказалось значение 571 Khz, , без резисторов на slave плате 276Khz. Но в обоих случаях при использовании пограничных значений частот передача либо начиналась и проходила без ошибок, либо ошибки сыпались бесконечно. У меня такое ощущения что что-то криво в коде, я прав?
Код для работы с i2c на мастере:

void i2cInit(void)
{
// set pull-up resistors on I2C bus pins
sbi(PORTD, 0); // i2c SCL on ATmega128,64 !!!!!!!!!!!!!!!!!!!!!
sbi(PORTD, 1); // i2c SDA on ATmega128,64 !!!!!!!!!!!!!!!!!!!!!


// clear SlaveReceive and SlaveTransmit handler to null
i2cSlaveReceive = 0;
i2cSlaveTransmit = 0;
// set i2c bit rate to 100KHz
i2cSetBitrate(276);
// enable TWI (two-wire interface)
sbi(TWCR, TWEN);
}

void i2cSetBitrate(u16 bitrateKHz)
{
u08 bitrate_div;
// calculate bitrate division
bitrate_div = ((F_CPU/1000l)/bitrateKHz);
if(bitrate_div >= 16)
bitrate_div = (bitrate_div-16)/2;
outb(TWBR, bitrate_div);
}

void i2cSetLocalDeviceAddr(u08 deviceAddr, u08 genCallEn)
{
// set local device address (used in slave mode only)
outb(TWAR, ((deviceAddr&0xFE) | (genCallEn?1:0)) );
}
inline void i2cSendStart(void)
{
// send start condition
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
}

inline void i2cSendStop(void)
{
// transmit stop condition
// leave with TWEA on for slave receiving
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA)|BV(TWSTO));
}

inline void i2cWaitForComplete(void)
{
// wait for i2c interface to complete operation
while( !(inb(TWCR) & BV(TWINT)) ){if(wait>2000){wait=0;return;}else{wait++;}}
}

inline void i2cSendByte(u08 data)
{
// save data to the TWDR
outb(TWDR, data);
// begin send
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
}

inline void i2cReceiveByte(u08 ackFlag)
{
// begin receive over i2c
if( ackFlag )
{
// ackFlag = TRUE: ACK the recevied data
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
}
else
{
// ackFlag = FALSE: NACK the recevied data
outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
}
}

inline u08 i2cGetReceivedByte(void)
{
// retieve received data byte from i2c TWDR
return( inb(TWDR) );
}

inline u08 i2cGetStatus(void)
{
// retieve current i2c status from i2c TWSR
return( inb(TWSR) );
}u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data)
{
u08 retval = I2C_OK;



// send start condition
i2cSendStart();
i2cWaitForComplete();

// send device address with write
i2cSendByte( deviceAddr & 0xFE );
i2cWaitForComplete();

// check if device is present and live
if( inb(TWSR) == TW_MT_SLA_ACK)
{
// send data
while(length)
{
i2cSendByte( *data++ );
i2cWaitForComplete();
length--;
}
}
else
{
// device did not ACK it's address,
// data will not be transferred
// return error
retval = I2C_ERROR_NODEV;
}

// transmit stop condition
// leave with TWEA on for slave receiving
i2cSendStop();
i2cWaitForComplete();


return retval;
}

u08 i2cMasterReceiveNI(u08 deviceAddr, u08 length, u08 *data)
{
u08 retval = I2C_OK;


// send start condition
i2cSendStart();
i2cWaitForComplete();

// send device address with read
i2cSendByte( deviceAddr | 0x01 );
i2cWaitForComplete();

// check if device is present and live
if( inb(TWSR) == TW_MR_SLA_ACK)
{
// accept receive data and ack it
while(length > 1)
{
i2cReceiveByte(TRUE);
i2cWaitForComplete();
*data++ = i2cGetReceivedByte();
// decrement length
length--;
}

// accept receive data and nack it (last-byte signal)
i2cReceiveByte(FALSE);
i2cWaitForComplete();
*data++ = i2cGetReceivedByte();
}
else
{
// device did not ACK it's address,
// data will not be transferred
// return error
retval = I2C_ERROR_NODEV;
}


// transmit stop condition
// leave with TWEA on for slave receiving
i2cSendStop();
i2cWaitForComplete();

return retval;
}

резисторы 5.1 КОм.
Go to the top of the page
 
+Quote Post
stells
сообщение Jul 21 2012, 16:13
Сообщение #2


внештатный сотрудник
******

Группа: Участник
Сообщений: 2 458
Регистрация: 10-05-08
Из: МО, Медвежьи озера
Пользователь №: 37 401



Цитата(the_spirit @ Jul 21 2012, 18:06) *
У меня такое ощущения что что-то криво в коде, я прав?
...
резисторы 5.1 КОм.

код смотреть неинтересно, интересно в первую очередь посмотреть осциллограммы сигналов, фронты
Go to the top of the page
 
+Quote Post
-SANYCH-
сообщение Jul 22 2012, 08:17
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 289
Регистрация: 6-12-05
Пользователь №: 11 864



Цитата
Но в обоих случаях при использовании пограничных значений частот передача либо начиналась и проходила без ошибок, либо ошибки сыпались бесконечно.


Исходя из вашего ответа, у Вас проблема в длинном кабеле, а не в коде. Проверяется это легко: соедините устройство сначала без кабеля (коротким проводом) и протестируйте, а потом с кабелем и тоже протестируйте на ошибки. Если с кабелем будут ошибки, а без кабеля нет, значит, ваша программа работает нормально.
Go to the top of the page
 
+Quote Post
the_spirit
сообщение Jul 22 2012, 14:28
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 25-11-10
Из: Красногорск
Пользователь №: 61 170



Да не, с коротким кабелем все работает, и даже с длинным на стандартной частоте. Меня беспокоит то, что при повышении частоты устройство перестает работать внезапно. У меня в программе считаются доставленные и не доставленные посылки, и при переходе в 1 khz, например от 571 к 572 посылки перестают доставляться совсем, и нет ситуации при которой доходила бы например половина или одна треть от всех отправленных посылок.

Осциллограммы можно устроить, но это не раньше понедельника. В принципе для разных частот картинка не отличается, тоесть фронты сильно завалены но приблизительно одинаково что для 570 khz что для 571.
Go to the top of the page
 
+Quote Post
stells
сообщение Jul 22 2012, 14:48
Сообщение #5


внештатный сотрудник
******

Группа: Участник
Сообщений: 2 458
Регистрация: 10-05-08
Из: МО, Медвежьи озера
Пользователь №: 37 401



Цитата(the_spirit @ Jul 22 2012, 18:28) *
Да не, с коротким кабелем все работает, и даже с длинным на стандартной частоте.

так а для чего Вы блох ловите, если работает? начиная с определенной частоты строб чтения бита приходит в тот момент, когда уровень сигнала не достиг порогового уровня из-за завала фронта
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jul 22 2012, 14:50
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(the_spirit @ Jul 22 2012, 17:28) *
и при переходе в 1 khz, например от 571 к 572 посылки перестают доставляться совсем, и нет ситуации при которой доходила бы например половина или одна треть от всех отправленных посылок.

Разве максимальная частота не 400 кГц?
На 571 кГц TWI вообще не обязано работать. Да ещё и на 10 м.
Go to the top of the page
 
+Quote Post
the_spirit
сообщение Jul 22 2012, 15:14
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 25-11-10
Из: Красногорск
Пользователь №: 61 170



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

Ну в том то и проблема, что на предельной частоте, иногда передача срабатывает, и, если срабатывает, то Master и Slave могут обмениваться сообщениями довольно продолжительное время.Мне этот процесс не понятен, и это меня напрягает.

Сообщение отредактировал the_spirit - Jul 22 2012, 15:19
Go to the top of the page
 
+Quote Post
stells
сообщение Jul 22 2012, 15:39
Сообщение #8


внештатный сотрудник
******

Группа: Участник
Сообщений: 2 458
Регистрация: 10-05-08
Из: МО, Медвежьи озера
Пользователь №: 37 401



Цитата(the_spirit @ Jul 22 2012, 19:14) *
Ну было интересно посмотреть до какой частоты можно разогнать интерфейс.

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

Цитата(the_spirit @ Jul 22 2012, 19:14) *
Мне этот процесс не понятен

а чтобы процесс понять, нужно смотреть осциллограммы
Go to the top of the page
 
+Quote Post
the_spirit
сообщение Jul 22 2012, 16:27
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 25-11-10
Из: Красногорск
Пользователь №: 61 170



Ок, спасибо, попробуем. Осциллограммы постараюсь к понедельнику сделать, если успею разобраться как осцил к компу подключается, раньше не было необходимости)
Go to the top of the page
 
+Quote Post
Ruslan1
сообщение Jul 22 2012, 19:31
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 360
Регистрация: 6-03-06
Из: Кишинев
Пользователь №: 15 025



Цитата(the_spirit @ Jul 22 2012, 17:28) *
Меня беспокоит то, что при повышении частоты устройство перестает работать внезапно. У меня в программе считаются доставленные и не доставленные посылки, и при переходе в 1 khz, например от 571 к 572 посылки перестают доставляться совсем, и нет ситуации при которой доходила бы например половина или одна треть от всех отправленных посылок.

Внутри шага в один килогерц есть еще много мааааленьких шажочков. Если бы Вы двигались не на килогерц, а , например на герц или на микрогерц, то наверняка бы смогли зафиксировать любой процент ошибок от 0 до 100% с любым нужным Вам разрешением (скажем, 17.097% ошибок на частоте 570192.55 Гц). Также Вы можете построить функцию зависимости количества ошибок на такой пограничной частоте от излучения солнца или скорости ветра в лаборатории. Только зачем все это?

P.S. Есть такой экспресс-тест линии связи- подать меандр (скажем, 1КГц) и снять осциллограмму. На основании исследования фронтов со стороны приемника можно прогнозировать, что через этот провод можно прокачать без ошибок, что с ошибками, а что вообще не пролезет. Это- аргументированно и обосновано. То что делаете Вы- метод ненаучного тыка. У Вас на столе сегодня результат такой, завтра у соседа что-то другое получится.
Go to the top of the page
 
+Quote Post
the_spirit
сообщение Jul 22 2012, 21:15
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 25-11-10
Из: Красногорск
Пользователь №: 61 170



Да, спасибо за разъяснение. По шине SCL фактически и передается меандр, осциллограммы смотрел с нее со стороны приемника , фронты завалены, работе это не мешает. Про более мелкий шаг думал, вопрос собственно был в том, почему на пограничной частоте интерфейс то работает то нет, и не связанно ли это с ошибкой в коде.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jul 22 2012, 21:56
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Вы библиотеки откуда брали?


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
the_spirit
сообщение Jul 22 2012, 22:04
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 25-11-10
Из: Красногорск
Пользователь №: 61 170



Из AVR Libc пришлось чуть чуть поменять чтобы заработала под IAR и не зависала.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jul 22 2012, 22:09
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Тогда код можно смело вычёркивать из списка , а остальное уже написал RUSLAN1


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
the_spirit
сообщение Jul 22 2012, 22:12
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 25-11-10
Из: Красногорск
Пользователь №: 61 170



Спасибо!
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 21:33
Рейтинг@Mail.ru


Страница сгенерированна за 0.01482 секунд с 7
ELECTRONIX ©2004-2016