код изменял в соответствии с тем который описан в ссылке
CODE
#define ADR24AA1025 0xA0 //Адрес карты памяти
#define ADDR_HI 0x08 // Выбор верхней или нижний части памяти
#define ADDR_LOW 0x0
#define CARD_ADDR1 0 //4 карты памяти на шине
#define CARD_ADDR2 2 //
#define CARD_ADDR3 4 //
#define CARD_ADDR4 6
#define READ 0x01 // I2C бит чтения
#define SERIAL_FLASH_DATA 4 // I2C данные: Порт D бит 4
#define SERIAL_FLASH_SCL 5 // I2C строб: Порт D бит 5
#define QDEL delay_us(10) // задержка 10мкс
#define HDEL delay_us(20) // задержка 20мкс
#define I2C_SDL_LO PORTD.OUTCLR&=(1<<SERIAL_FLASH_DATA); // DATA = 0
#define I2C_SDL_HI PORTD.OUTSET|=(1<<SERIAL_FLASH_DATA); // DATA = 1
#define I2C_SCL_LO PORTD.OUTCLR&=(1<<SERIAL_FLASH_SCL); //аналогично
#define I2C_SCL_HI PORTD.OUTSET|=(1<<SERIAL_FLASH_SCL);
#define OUT(BIT) (PORTD.DIRSET|=(1<<BIT))
#define IN(BIT) (PORTD.DIRCLR&=(1<<BIT))
#define I2C_SCL_TOGGLE HDEL; I2C_SCL_HI; HDEL; I2C_SCL_LO;
#define I2C_START I2C_SDL_LO; QDEL; I2C_SCL_LO;
#define I2C_STOP HDEL; I2C_SCL_HI; QDEL; I2C_SDL_HI; HDEL;
// Запись байта на устройство
bool i2cPutbyte(uint8_t

{
int8_t i;
uint8_t j;
rtcTime.status=0;
j=0x80;
for (i=7;i>=0;i--)
{
if ( b & j )
I2C_SDL_HI;
else
I2C_SDL_LO; // address bit
I2C_SCL_TOGGLE; // clock HI, delay, then LO
j >>= 1;
}
IN(SERIAL_FLASH_DATA); // change direction to input on SDA line (may not be needed)
I2C_SDL_HI; // leave SDL HI
// added
HDEL;
I2C_SCL_HI; // clock back up
HDEL;
b = (PORTD.IN&SERIAL_FLASH_DATA); // get the ACK bit
rtcTime.status=b;
//отслеживаю АСК и через раз он равен 1. I2C_SCL_LO; // not really ??
OUT(SERIAL_FLASH_DATA); // change direction back to output
HDEL;
return (b == 0); // return ACK value
}
// чтение байта из устройство
uint8_t i2cGetbyte(uint8_t last)
{
int i;
uint8_t b = 0;
I2C_SDL_HI; // make sure pullups are ativated
IN(SERIAL_FLASH_DATA); // change direction to input on SDA line (may not be needed)
for(i=7;i>=0;i--)
{
HDEL;
I2C_SCL_HI; // clock HI
if((PORTD.IN&(1<<SERIAL_FLASH_DATA))!=0){ b |= 1;} //
Может быть что-то здесь? b <<= 1;
HDEL;
I2C_SCL_LO; // clock LO
}
OUT(SERIAL_FLASH_DATA); // change direction to output on SDA line
if (last)
I2C_SDL_HI; // set NAK
else
I2C_SDL_LO; // set ACK
I2C_SCL_TOGGLE; // clock pulse
I2C_SDL_HI; // leave with SDL HI
return b; // return received byte
}
//! Initialize I2C communication
void i2cInit(void)
{
OUT(SERIAL_FLASH_DATA); // set SDA as output
OUT(SERIAL_FLASH_SCL); // set SCL as output
I2C_SDL_HI; // set I/O state and pull-ups
I2C_SCL_HI; // set I/O state and pull-ups
}
//Чтение одного байта с указанием адреса
uint8_t i2ceepromReadByte(uint16_t memAddr,unsigned char card,bool H_L)
{
uint8_t i2cAddr=0;
I2C_START;
if (H_L) i2cAddr=((ADR24AA1025&0xfe)||ADDR_HI||card);
else i2cAddr=((ADR24AA1025&0xfe)||card);
i2cPutbyte(i2cAddr));
i2cPutbyte((memAddr>>8) & 0xff)
i2cPutbyte(memAddr & 0xff);
HDEL;
I2C_SCL_HI; // do a repeated START
I2C_START; // transition
while(!i2cPutbyte(i2cAddr||READ)); // resend DEVICE, with READ bit set
memAddr = i2cGetbyte(1);
I2C_SDL_LO; // clear data line and
I2C_STOP; // send STOP transition
return ((uint8_t)memAddr);
}
// Запись одного байта с указанием адреса
void i2ceepromWriteByte(uint16_t memAddr,unsigned char card, bool H_L, uint8_t data)
{
uint8_t i2cAddr=0;
I2C_START;
if (H_L) i2cAddr=((ADR24AA1025&0xfe)||ADDR_HI||card);
else i2cAddr=((ADR24AA1025&0xfe)||card);
i2cPutbyte(i2cAddr);
i2cPutbyte((memAddr>>8) & 0xff)
i2cPutbyte(memAddr & 0xff);
i2cPutbyte(data);
I2C_SDL_LO; // clear data line and
I2C_STOP; // send STOP transition
}
Цитата
Как вы умудряетесь читать 255, если единице на шине без подтяжек взяться просто неоткуда - загадка. Разберитесь с этим, будем смотреть дальше.
Самому интересно. Буду пытаться найти ошибку.
Вызов идет вот отсюда
CODE
i2ceepromWriteByte(0,CARD_ADDR1, 0, 15); //Пишу значение 15 на младшую часть памяти 1, с адресом 0.
Digit(rtcTime.status); // отслеживаю АСК
i2ceepromWriteByte(0,CARD_ADDR1, 0, 15);
Digit(rtcTime.status);
i2ceepromWriteByte(0,CARD_ADDR1, 0, 15);
Digit(rtcTime.status);
i2ceepromWriteByte(1,CARD_ADDR2, 0, 15);
Digit(rtcTime.status);
i2ceepromWriteByte(1,CARD_ADDR2, 0, 15);
Digit(rtcTime.status);
i2ceepromWriteByte(1,CARD_ADDR2, 0, 15);
Digit(rtcTime.status);
Digit(i2ceepromReadByte(0,CARD_ADDR1,0)); // читаю и вывожу на экран
Digit(rtcTime.status); // слежу за АСК
Digit(i2ceepromReadByte(0,CARD_ADDR1,0));
Digit(rtcTime.status);
Digit(i2ceepromReadByte(0,CARD_ADDR1,0));
Digit(rtcTime.status);
Digit(i2ceepromReadByte(1,CARD_ADDR2,0));
Digit(rtcTime.status);
Digit(i2ceepromReadByte(1,CARD_ADDR2,0));
Digit(rtcTime.status);
Digit(i2ceepromReadByte(1,CARD_ADDR2,0));
Digit(rtcTime.status);
Digit(i2ceepromReadByte(1,CARD_ADDR3,0));
Digit(rtcTime.status);
Digit(i2ceepromReadByte(1,CARD_ADDR3,0));
Digit(rtcTime.status);
Digit(i2ceepromReadByte(1,CARD_ADDR3,0));
Digit(rtcTime.status);
Данный результат
0 0 4 0 0 0 // АСК=1 при 3 записи... Динамически изменяется при прошивке
|| 1 ячейка 1 пам ||2 ячейка 2 пам || карта 3 3 пам || Карта 3 пока что отсутсвует. Читать нечего. Но появляются какие-то данные.
44 0 218 0 150 0 186 0 110 0 182 0 36 0 150 0 222 0 Похоже что сеанс чтения прошел без ошибок. Но почему тогда читаемые с одной ячейки постоянно меняются? Плавающий адрес?
Сообщение отредактировал IgorKossak - Jul 21 2011, 14:20