[an error occurred while processing this directive]
А вот хочу спросить по работе с I2C (работаю на PIC-16 с компилятором HI-TECH) (+)
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Прохожий 10 февраля 2003 г. 11:26

Надо работать (читать/писать) в микросхему Serial EEPROM AT24C...
До этого я работал на 51-м процессоре (у него порты квазидвунаправленные). А теперь вот работаю на PIC16 и тоже "с ходу" написал функцию для работы по I2C. Они заработали и типа все нормально. Но вот я написал тестовую программку, которая все время читает информацию из этой микросхемы в бесконечном цикле. И вот если теперь посмотреть осциллографом, то эта бадяга все время имеет проблемы по питанию - просто иногда я должен что-то выдать по I2C (ножка настроена на выход), а потом посмотреть на подтверждение (эту же ножку перевести на вход и читать состояние порта). И вот в какой-то момент бывает, что мне уже микросхема выдает сигнал подтверждения (она на выход), но и я еще не успел ножку на вход настроить - получается конфликт и по питанию прогодят такие вот "пички". Когда я работаю с I2C очень редко, например, вычитать один раз что-то при старте (уставки, например), то я этого и не замечал. Но вот такую вот штуку выловил на тестовой программе.
Я посмотрел на пример работы с I2C, который шел к компилятору PICC, и вот что я там увидел :

#define SCL_DIR TRISB2
#define SCL RB2
#define SDA_HIGH() SDA = 1; SDA_DIR = I2C_OUTPUT
#define SDA_LOW() SDA = 0; SDA_DIR = I2C_OUTPUT
#define I2C_INPUT 1 /* data direction input */
#define I2C_OUTPUT 0 /* data direction output */
unsigned char i2c_SendByte(unsigned char byte)
{
signed char i;
for(i=7; i>=0; i--) {
SCL_LOW(); /* drive clock low */
/* data hold time = 0, send data now */
SDA_DIR = ((byte>>i)&0x01);
if ((byte>>i)&0x01) { /* bit to send */
SDA_HIGH();
}
else {
SDA_LOW();
}
DelayUs(I2C_TM_DATA_SU);
SCL_DIR = I2C_INPUT; /* float clock high */

if(i2c_WaitForSCL()) /* wait for clock release */
return TRUE; /* bus error */

DelayUs(I2C_TM_SCL_HIGH); /* clock high time */
}
return FALSE;
}


Видим, что когда надо послать бит 1, они
SDA_DIR = ((byte>>i)&0x01); // если бит равен 1 - настраиваем на вход (в TRIS пишем 1)
а затем
if ((byte>>i)&0x01) {
SDA_HIGH() // что означает SDA = 1; SDA_DIR = I2C_OUTPUT
}
т. е. снова настраиваем SDA_DIR на выход.

Будет ли этот пример работать корректно? Как следует поступать в подобных случаях ? Подскажите!

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru