I2C EEPROM
Pavel Hudecek
edizon na seznam.cz
Pondělí Říjen 8 13:50:57 CEST 2012
Tak asi půjdu koupit novou a pro jistotu ještě nějakou další, tentokrát
třeba s SPI:-)
Chová se stále stejně, tzn. pokud je správná adresa na I2C, odpovídá 0 při
ACK. Při čtení čte všude 255, akorát na adresách 3 a 5 je 161. Vypadá to,
jako kdyby prostě "jen" nezapisovala. Na vývodu WP jsem zkoušel nezapojeno,
0, i 1, ale vždy stejný výsledek.
Funkce i2cByteR a i2cByteW používá i převodník MCP3426 a funguje.
Při čtení:
at24adr(0,1);
dispInt(i2cAck);
dispInt(at24rdB()); dispInt(at24rdB());
dispInt(at24rdB()); dispInt(at24rdB());
dispInt(at24rdB()); dispInt(at24rdB());
dispInt(at24rdB()); dispInt(at24rdB());
vyleze:
0 255 255 255 161 255 161 255 255 ...
při jiné počáteční adrese se posunou pozice, na kterých je 161.
při zápisu:
dispInt(at24wrB(0,100)); delay_ms(6);
dispInt(at24wrB(1,101)); delay_ms(6);
dispInt(at24wrB(2,102)); delay_ms(6);
dispInt(at24wrB(3,103)); delay_ms(6);
vyleze:
0 0 0 0
Stejný výsledek je, i když vynechám čekání mezi zápisy.
#define MCP_adr 0b11010000
#define MCP_wait delay_us(2);
#define AT24_adr 0b10100000
SDA_dir je bit z DDR registru od portu s SDA
SDA_in je bit z PIN registru od portu s SDA
SCL_dir je bit z DDR registru od portu s SCL
unsigned char i2cImp(unsigned char b) { // poslat/precist bit
unsigned char i;
SDA_dir=!b; MCP_wait
SCL_dir=0; MCP_wait
i=SDA_in;
SCL_dir=1;
return i;
}
void i2cStart() {
SDA_dir=1; MCP_wait
SCL_dir=1; MCP_wait
}
void i2cStop() {
MCP_wait
SCL_dir=0; MCP_wait
SDA_dir=0; MCP_wait
}
void i2cByteW(unsigned char b) { // zapis bytu do I2C
unsigned char n;
for (n=7; n<8; n--) {
i2cImp(b&(1<<n));
MCP_wait
}
i2cAck=(i2cAck<<1)+i2cImp(1);
}
unsigned char i2cByteR(unsigned char a) {
// cteni bytu z I2C, jako parametr ACK
unsigned char n, b=0;
for (n=7; n<8; n--) {
b=b<<1;
b|=i2cImp(1);
MCP_wait
}
i2cImp(a);
return b;
}
unsigned char at24adr(unsigned short a, unsigned char s) {
// adresa, stop ano/ne, vraci 3x ack
i2cStart();
i2cAck=0;
i2cByteW(AT24_adr+0);
i2cByteW((unsigned char)(a>>8));
i2cByteW((unsigned char)(a & 255));
if (s==1) i2cStop();
return i2cAck;
}
unsigned char at24wrB(unsigned short a, unsigned char b) {
// zapsat 1 B do eeprom, vraci 4x ack
at24adr(a,0);
i2cByteW(b);
i2cStop();
return i2cAck;
}
unsigned char at24rdB() { // cteni 1 B z eeprom
unsigned char n, b=0;
i2cStart();
i2cByteW(AT24_adr+1);
b=i2cByteR(0);
i2cStop();
return b;
}
Děkuji,
PH
From: "Pavel Hudecek" <edizon na seznam.cz>
mám subj, přesněji řečeno AT24C256C-SSHL-B.
S ní komunikuje ATmega8. Na lince je zároveň AD převodník, ten funguje.
EEPROM se také tváří funkčně. Po zápisu z ní vyleze ACK. Čtení taky skončí
úspěšně.
Jenže ať zapíšu cokoli, kamkoli, stejně přečtu všude 255, jen na adresách 3
a 5 se nachází 161. Zajímavé také je, že i když je zvenku zapnuté WP, po
zápisu přijde ACK, jakoby bylo vše ok.
V čem by mohl být problém?
Další informace o konferenci Hw-list