EEPROM存储器24C16,,24C64读写都完全正确,但读写铁电FM24C04B...
同一程序,EEPROM存储器24C16,,24C64读写都完全正确,但读写铁电FM24C04B就会出错,问题到底出在哪里?
用AVR的TWI模块和端口模拟I2C总线都试过了,24C16,,24C64读写都完全正确,但读写铁电FM24C04B就是会出错,有时也能读写正确
真不知道问题出在哪里,哪位大侠能指点一下关键啊
因为手上没有EEPROM存储器24C04,所以没试过
写铁电和EEPROM存储器驱动程序该注意什么?求教…… 很明显的问题,24C16是双字节地址,04是 单字节地址 armandusb 发表于 2012-7-11 20:57 static/image/common/back.gif
很明显的问题,24C16是双字节地址,04是 单字节地址
我操作24C16也是单字节地址操作,24C16应该也算是单字节地址,在同一页的操作应该是一样的,只是24C16是8页,24C04是2页
附上程序:
/*******************写*****************/
uchar I2C_Write(uchar addr,uchar udata)
{
uchar err;
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //发出STATA信号
err = 200;
while((!(TWCR & (1<<TWINT))))
{
if(--err==0)
{
return 1;
}
}
TWDR = sLOVADDR|WRITE; //从器件地址
TWCR = (1<<TWINT)|(1<<TWEN);
err = 200;
while((!(TWCR & (1<<TWINT))))
{
if(--err==0)
{
return 2;
}
}
TWDR = addr; //字节地址
TWCR = (1<<TWINT)|(1<<TWEN);
err = 200;
while((!(TWCR & (1<<TWINT))))
{
if(--err==0)
{
return 3;
}
}
TWDR = udata; //发送数据
TWCR = (1<<TWINT)|(1<<TWEN);
err = 200;
while((!(TWCR & (1<<TWINT))))
{
if(--err==0)
{
return 4;
}
}
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); ////发出STOP信号
return 0;
}
/****************读*********************/
uchar I2C_Read(uchar addr)
{
//uchar udata=0;
uchar err;
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //发出STATA信号
err = 20;
while(!(TWCR & (1<<TWINT)))
{
if(--err==0)
{
return 1;
}
}
TWDR = sLOVADDR|WRITE; //从器件地址
TWCR = (1<<TWINT)|(1<<TWEN);
err = 200;
while(!(TWCR & (1<<TWINT)))
{
if(--err==0)
{
return 2;
}
}
TWDR = addr; //字节地址
TWCR = (1<<TWINT)|(1<<TWEN);
err = 200;
while(!(TWCR & (1<<TWINT)))
{
if(--err==0)
{
return 3;
}
}
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //发出STATA信号
err = 200;
while(!(TWCR & (1<<TWINT)))
{
if(--err==0)
{
return 4;
}
}
TWDR = sLOVADDR|READ; //从器件地址-读数据
TWCR = (1<<TWINT)|(1<<TWEN);
err = 200;
while(!(TWCR & (1<<TWINT)))
{
if(--err==0)
{
return 5;
}
}
TWCR = (1<<TWINT)|(1<<TWEN);//|(1<<TWEA);
err = 200;
while(!(TWCR & (1<<TWINT)))
{
if(--err==0) ////读数据
{
return 6;
}
}
ReveValue_g = TWDR;
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN); ////发出STOP信号
return 0;
}
端口模拟:
/*************发送START****************/
void start(void)
{
SCL_H;
SDA_H;
//_delay_us(DELAY);
SDA_L;
SCL_L;
}
/*************发送STOP****************/
void stop(void)
{
SDA_L;
SCL_L;
//_delay_us(DELAY);
SDA_H;
//_delay_us(DELAY);
SCL_L;
}
/*************判断ACK****************/
uchar ack(void)
{
uchar err;
SDA_IN;
SCL_H;
//_delay_us(DELAY);
if(SDAIN())
return 1;
SCL_L;
SDA_OUT;
return 0;
}
/*************发送NACK****************/
void Nack(void)
{
SDA_H;
SCL_H;
//_delay_us(DELAY);
SCL_L;
}
/*************写函数****************/
void write(uchar data)
{
uchar i;
for(i=0;i<8;i++)
{
if((data<<i)&0x80)
SDA_H;
else
SDA_L;
SCL_H;
//_delay_us(DELAY);
SCL_L;
}
}
/*************读函数****************/
uchar read(void)
{
uchar i,data=0;
SDA_IN;
for(i=0;i<8;i++)
{
SCL_H;
//_delay_us(DELAY);
if(SDAIN())
data |= 0x80>>i;
SCL_L;
}
SDA_OUT;
return data;
}
/*************写数据****************/
uchar I2cWrByte(uchar addr,uchar data)
{
start();
write(EEPADDR|WRITE);
if(ack())
{
return 1;
}
//write(addr>>8);
//if(ack())
//{
// return 1;
//}
write(addr);
if(ack())
{
return 2;
}
write(data);
if(ack())
{
return 3;
}
stop();
return 0;
}
/*************读数据****************/
uchar I2cRdByte(uchar addr)
{
//uchar data;
start();
write(EEPADDR|WRITE);
if(ack())
{
return 1;
}
//write(addr>>8);
//ack();
write(addr);
if(ack())
{
return 2;
}
start();
write(EEPADDR|READ);
if(ack())
{
return 3;
}
ReveValue_g=read();
Nack();
stop();
return 0;
} 你再仔细看看手册,确认设备地址对吗。铁电和EEPROM时序应该没啥区别,铁电写还不用等待。更可能是04和16区别造成的 你看看16和04的资料再说吧!16是单地址操作?能弄通才是怪事! armandusb 发表于 2012-7-13 13:42 static/image/common/back.gif
你看看16和04的资料再说吧!16是单地址操作?能弄通才是怪事!
24c01/04/08/16的确是单一存储器地址,只不过分页多少不同。看图:
sf49ers 发表于 2012-7-11 22:26 static/image/common/back.gif
你再仔细看看手册,确认设备地址对吗。铁电和EEPROM时序应该没啥区别,铁电写还不用等待。更可能是04和16区 ...
赞同。另外,铁电存储器写入零等待;还有,不存在EEPROM的分页概念,如果有多字节写入的话,连续顺序写即可。 armandusb 发表于 2012-7-13 13:42 static/image/common/back.gif
你看看16和04的资料再说吧!16是单地址操作?能弄通才是怪事!
可能是我们的理解单字节,双字节不同,
我的理解是:发送设备地址A0+分页地址+W/R之后,发送一字节地址,我认为是单字节操作;如果你认为分页地址也算一字节,那24C04也是双字节
而像24C64需要发送两个字节地址的,是双字节操作 zpxa001 发表于 2012-7-13 14:30 static/image/common/back.gif
赞同。另外,铁电存储器写入零等待;还有,不存在EEPROM的分页概念,如果有多字节写入的话,连续顺序写即 ...
当总线速度100K的时候,总是经常出错,
现在把总线提高到400K,基本上就没问题了
难道是铁电对低速不屑{:titter:}
请教一下这是为什么? 有完整例程吗?
页:
[1]