I2C连续读的时候发送应答型号应该是怎样的?
下面是程序,从电容触摸屏中读取坐标,问题是如果我每次只读一个地址的数据就没问题,连续读取的话就会都是第一个地址的数据,void i2c_master_send_ACK( void)
{
SDA = 1;
i2c_delay();
SCL = 1;
i2c_delay();
SCL = 0;
i2c_delay();
}
这里发送应答应该是将SDA=0才感觉是对的,要拉低SDA给对方应答信号,但是如果这里发送SDA=0的话,
后面就连读一次的数据都会出现这个错误printf("msg i2c read error: %d\n",ret);
现在的程序至少执行ft5x06_i2c_rxdata(u8 *rxdata,u8 length)的length长度=1的不会出现任何错误
请帮忙看一下.
void i2c_delay(void)
{
u8 i=5;
while(i--);
}
void i2c_start(void)
{
SDA = 1;
SCL = 1;
i2c_delay();
SDA = 0;
i2c_delay();
SCL = 0;
i2c_delay();
}
void i2c_stop(void)
{
SDA = 0;
SCL = 1;
i2c_delay();
SDA = 1;
i2c_delay();
}
void i2c_master_send_ACK( void)
{
SDA = 1;
i2c_delay();
SCL = 1;
i2c_delay();
SCL = 0;
i2c_delay();
}
u8 i2c_master_recv_ACK(void)
{
u8 ACK=0;
SCL = 1;
i2c_delay();
ACK |= SDA;
i2c_delay();
SCL = 0;
i2c_delay();
return ACK;
}
u8 i2c_master_send_byte(u8 Byte)
{
u8 i,ACK;
for(i=0;i<8;i++)
{
SDA = Byte>>(7-i)&0x01;
i2c_delay();
SCL = 1;
i2c_delay();
SCL = 0;
i2c_delay();
}
ACK = i2c_master_recv_ACK();
return ACK; //ACK=1=失败,ACK=0=成功
}
u8 i2c_master_recv_byte( void )
{
u8 i,temp;
for(i=0;i<8;i++)
{
temp=temp<<1;
SCL = 1;
i2c_delay();
temp |= SDA;
SCL = 0;
i2c_delay();
}
return temp;
}
//i2c数据传输,每次传输一个数据包
int i2c_transfer_msg(u8 SlaveAddr_and_RorW , u8 *msg , u8 length)
{
int ret;
u8 i;
i2c_start();
ret = i2c_master_send_byte(SlaveAddr_and_RorW);
if(SlaveAddr_and_RorW&0x01) //RorW=1=Read
{
for(i=0;i<length;i++)
{
msg=i2c_master_recv_byte();
i2c_master_send_ACK();
}
}
else //RorW=0=Write
{
for(i=0;i<length;i++)
{
ret += i2c_master_send_byte(msg);
}
}
i2c_stop();
return ret; //=0表示没任何错误
}
//master从ft5x06中读数据,数据缓冲区第一个字节为起始读地址
static int ft5x06_i2c_rxdata(u8 *rxdata,u8 length)
{
int ret;
u8 SlaveAddr_and_RorW;
SlaveAddr_and_RorW = (ft5x06_I2C_SLAVE_ADDRESS<<1) + 0; //Write
ret = i2c_transfer_msg(SlaveAddr_and_RorW,rxdata,1);
SlaveAddr_and_RorW = (ft5x06_I2C_SLAVE_ADDRESS<<1) + 1; //Read
ret += i2c_transfer_msg(SlaveAddr_and_RorW,rxdata,length);
if(ret)
printf("msg i2c read error: %d\n",ret);
return ret; //=0表示没任何错误
}
I2C read的最后一个字节,主机不能发送ACK,否者总线可能死锁。
I2CREAD最后一个字节后(从机不知何为最后字节),若主机回应ACK,从机会自动将下一字节准备好,并将其高位输出到SDA上。若高位为0(SDA=0),主机发不出STOP信号(SDA不能由低变高),总线进入死锁态。
david1234 发表于 2014-7-22 15:10
I2C read的最后一个字节,主机不能发送ACK,否者总线可能死锁。
I2CREAD最后一个字节后(从机不知何为最后 ...
谢谢,这个问题我没注意到,要发送一个noack后再stop
但是现在还没到这个错误这里,连续读取的第二个字节就已经出错了,和第一个字节内容一样,感觉是应答没发好,从机没有把第二个字节准备好给我。 david1234 发表于 2014-7-22 15:10
I2C read的最后一个字节,主机不能发送ACK,否者总线可能死锁。
I2CREAD最后一个字节后(从机不知何为最后 ...
弄个超时,重发。 楼主,你的i2c_master_send_ACK、i2c_master_recv_ACK 、i2c_master_recv_byte 这些函数是错误的。
接收每个位之前,SDA应该先置1,这样才能接收到正确的数据位。
主机先发送应答 受5楼提示,在sendack中, sda=0。recack中,sda =1。你程序中刚好都反了。 laoshuhunya 发表于 2014-7-22 20:17
楼主,你的i2c_master_send_ACK、i2c_master_recv_ACK 、i2c_master_recv_byte 这些函数是错误的。
接收每 ...
先SDA=1的话,ret错误提示那里字符串狂出 可是我程序目前读写一个字节的时候都正常的呢...
我要另外找个i2c器件来验证一下i2c bias 发表于 2014-7-22 22:17
可是我程序目前读写一个字节的时候都正常的呢...
我要另外找个i2c器件来验证一下i2c ...
可以参考下这个帖子:
http://www.amobbs.com/forum.php?mod=viewthread&tid=5587231&page=1#pid7701082
david1234 发表于 2014-7-22 15:10
I2C read的最后一个字节,主机不能发送ACK,否者总线可能死锁。
I2CREAD最后一个字节后(从机不知何为最后 ...
如不幸出现此情况,该如何处理?做个超时对i2c从设备重新加电? 本帖最后由 david1234 于 2014-7-23 08:03 编辑
首先,最后一次读不发ACK就不死锁。若死锁,可连发9个时钟信号,再发STOP bias 发表于 2014-7-22 22:17
可是我程序目前读写一个字节的时候都正常的呢...
我要另外找个i2c器件来验证一下i2c ...
因为你的ACK 不对,所以后续通信都不正确 楼主,用下面函数,应该就好了:
void i2c_master_send_ACK( void)
{
SDA = 0;
i2c_delay();
SCL = 1;
i2c_delay();
SCL = 0;
i2c_delay();
}
void i2c_master_send_NAK( void)
{
SDA = 1;
i2c_delay();
SCL = 1;
i2c_delay();
SCL = 0;
i2c_delay();
}
u8 i2c_master_recv_ACK(void)
{
SDA=1
u8 ACK=0;
SCL = 1;
i2c_delay();
ACK |= SDA;
i2c_delay();
SCL = 0;
i2c_delay();
return ACK;
}
页:
[1]