关于430操作EEPROM的问题 有点奇怪
调试一个430读写24C02,时序我是按照user guide 中要求写的,觉得时序是没有问题,但是出现一个问题,在我写完控制位A0 有ACK 这个没有问题, 然后是地址为00,我也能写进去,同样有ACK,拉低SDA,也没有问题,
现象来了,就是在写数据的时候,却怎么也写不进去,表明没有应答信号,这一点,我很奇怪,问题在这:
(1)能写进去控制位A0有应答信号,证明SPI时序是没有问题的,然后是地址位00也有应答信号,更加证明我的SPI是正确的,不然不会有ACK,
但是在写数据的时候却怎么也写不进去,我很奇怪,想不通?
(2)由于24C02只有8位地址,照理写进去控制位A0 然后地址位,应该没有问题,就能写数据了,但是我发数据,却没有应答信号,一直返回错。
程序模块如下:
I2CStart();
I2CSendByte(ControlByte&0xfe); //Only write
if(!WaitAck())
continue;
I2CSendByte(Address);
if(!WaitAck())
continue;
if(!(ControlByte&0x01)) //write
{
errorflag=right;
while(ByteQuantity--)
{
I2CSendByte(*DataBuffer++);
if(WaitAck()) //enter next while loop
continue;
else
{
errorflag=error; // no ack stop while
break;
}
}
if(errorflag==error)
{
continue;
}
else
{
break; //finsh write
}
}
也就是在I2CSendByte(*DataBuffer++); 之后判断ACK ACK返回1 表明有应答信号,返回0没有,但是我执行完发送数据后,却看点 SDA的电平
没有拉低,能解释下么?我看过数据手册中的说明,一直没有查到原因,但我知道,写不进去肯定SPI的时序有问题,但是就找不原因,因为控制位和地址能写
很奇怪~~~~
希望能有高手回答下~~~谢谢~~~ 楼主“写进去控制位A0”是什么意思?
能不能看看“WaitAck()” 的代码? lcw_swust 发表于 2012-7-28 16:16 static/image/common/back.gif
楼主“写进去控制位A0”是什么意思?
能不能看看“WaitAck()” 的代码?
感谢你的回帖,waitAck() 是可以进去的 A0 是24c02的控制字 aizhixi106 发表于 2012-7-28 16:54 static/image/common/back.gif
感谢你的回帖,waitAck() 是可以进去的 A0 是24c02的控制字
"waitAck() 是可以进去的"不代表这个函数没问题
“A0 是24c02的控制字”这是第一次听说 lcw_swust 发表于 2012-7-28 16:56 static/image/common/back.gif
"waitAck() 是可以进去的"不代表这个函数没问题
“A0 是24c02的控制字”这是第一次听说 ...
你好,我明白你的意思,A0是 1010 0000 这个是开始的控制位啊~~~24C02开始时候发送这个,然后会收到ACK ,SDA收到拉低电平,你说WiatAck()有问题
但是在我发送完地址位置后看到SDA 能被拉低。说明应该没有问题啊~~~如果有问题,说明在发送sda收不到拉低电平啊?
对么?
lcw_swust 发表于 2012-7-28 16:16 static/image/common/back.gif
楼主“写进去控制位A0”是什么意思?
能不能看看“WaitAck()” 的代码?
unsigned charWaitAck()
{
unsigned char errtime=255;
SDA1;
SomeNop();
SCL1;
SomeNop();
SDAIN;
while(SDA_STATE)
{
errtime--;
if(!errtime)
{
I2CStop();
return NO;
}
}
SDAOUT;
SCL0;
return OK;
}
这个是WaitAck的代码
看了楼主的程序,貌似没问题,下面是我写的程序,给楼主参考参考:
#define SLAW 0XA0
#define SLAR 0XA1
#define PWP_H IOSET(P3,BIT(4))
#define PWP_L IOCLR(P3,BIT(4))
#define PSCL_H IOSET(P3,BIT(5))
#define PSCL_L IOCLR(P3,BIT(5))
#define PSDA_H IOSET(P3,BIT(6))
#define PSDA_L IOCLR(P3,BIT(6))
#define PINSDA (P3&BIT(6))
//------------------------------------------------
//IIC启始信号
//------------------------------------------------
void IICStart(void)
{
PSCL_H;
PSDA_H;
delayus(1);
PSDA_L;
delayus(1);
PSCL_L;
delayus(1);
}
//------------------------------------------------
//IIC终止信号
//------------------------------------------------
void IICEnd(void)
{
PSCL_L;
PSDA_L;
delayus(1);
PSCL_H;
delayus(1);
PSDA_H;
delayus(1);
}
//------------------------------------------------
//IIC回应
//------------------------------------------------
U8 IICACK(void) reentrant
{
U8 ret=0;
PSDA_H;//放开数据线
PSCL_H;
delayus(1);
if(PINSDA)ret=1;//读数据线
PSCL_L;
delayus(1);
return ret;
}
//------------------------------------------------
//IIC发出一字节数据
//------------------------------------------------
void IICSendByte(U8 sdata)reentrant//Thigh,Tlow>2US 就行
{
U8 i;
for(i=0;i<8;i++)//之前PSCL=0;
{
if(sdata&0x80)
PSDA_H;
else
PSDA_L;
delayus(1);//NOP(); //delayus()
PSCL_H;
delayus(1);//NOP();
PSCL_L;
sdata<<=1;//移位
}
}
//------------------------------------------------
//IIC读取一字节数据
//------------------------------------------------
U8 IICReadByte(void)reentrant
{
U8 ret,i;
PSDA_H;
for(i=0;i<8;i++)//之前PSCL=0;
{
ret<<=1;
delayus(1);//NOP();
PSCL_H;
delayus(1);//NOP();
if(PINSDA)ret|=1;
PSCL_L;
}
return ret;
}
//------------------------------------------------
//IIC存入一字节
//addr:地址
//wdata:数据
//返回:第一个ACK,为0是正常的
//------------------------------------------------
U8 IICEEPW(U16 addr,U8 wdata)//写入24C01
{
U8 pg;//页地址
U8 ack;
pg=addr>>8;
IICStart();
IICSendByte(SLAW|(pg<<1));
ack=IICACK();
IICSendByte(addr);
IICACK();
IICSendByte(wdata);
IICACK();
IICEnd();
delayms(6);
return ack;
}
//------------------------------------------------
//IIC读取一字节
//addr:地址
//rdata:返回读到的数据
//返回:第一个ACK,为0是正常的
//------------------------------------------------
U8 IICEEPR(U16 addr,U8 * rdata)reentrant//读一字节
{
U8 ack,d;
U8 pg;//页地址
pg=addr>>8;
IICStart();
IICSendByte(SLAW|(pg<<1));
ack=IICACK();
IICSendByte(addr);//伪写操作
IICACK();
IICStart();
IICSendByte(SLAR|(pg<<1));
IICACK();
d=IICReadByte();
IICACK();
IICEnd();
*rdata=d;
return ack;
} lcw_swust 发表于 2012-7-29 15:25 static/image/common/back.gif
看了楼主的程序,貌似没问题,下面是我写的程序,给楼主参考参考:
#define SLAW 0XA0
#define SLAR 0XA ...
我就发送的A0 然后地址 这样没有问题吧? 我看见的程序 怎么左移后右移 为什么不直接发送A0? 不理解 你为什么那么做?当然你的地址是16为的 为什么不给8位的? 而是要通过移位?
现在出现写偶数可以,写奇数,写不进去?好奇怪~~~
页:
[1]