[an error occurred while processing this directive]
|
Надо работать (читать/писать) в микросхему 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