大家好、
我们有一个旧设计、在该设计中、我们曾将数据读取为 I2C 主器件。 代码准备只读取1个字节、现在我们已更改了 I2C 从设备、我们需要读取一些寄存器的2个数据字节。
寄存器地址的写入序列正确完成。 但是、读取序列有一些问题。
中的 NACK 在获得最后一个数据字节后未发送、它会发送一个额外的字节(通过示波器看到)。 我不知道我们是否正在正确执行该操作、但我们在读取第二个到最后一个字节后将 NACKMOD 寄存器位设置为1。 以下是该函数的代码、欢迎您提出任何建议:
Int16 i2c_OEM_readX( Uint8 deviceAddr, Uint8* RegAddr, Uint8 regLen, Uint8* data, Uint8 dataLen){
Uint16 ret = 0;
Uint8 tempByte;
int i;
while(I2C_REG0->ICSTR.bit.BB); //wait for bus to be not busy
//Just send SLA+R if no register bytes to send
if(regLen !=0){
//SET BYTE COUNT (dataLen+1)
I2C_REG0->ICCNT.bit.ICDC = regLen;
I2C_REG0->ICMDR.bit.MST = 1; //make sure we're in master mode
I2C_REG0->ICMDR.bit.TRX = 1; //make sure we're in transmit mode to send register address
//set up the slave address
I2C_REG0->ICSAR.bit.SADDR = deviceAddr >> 1;
//send the START condition and the slave address
I2C_REG0->ICMDR.bit.STT = 1;
//wait for START condition and slave address to go out
waitloop(10000);
//check for a NACK
if(I2C_REG0->ICSTR.bit.NACK)
{
I2C_REG0->ICMDR.bit.STP = 1;
return(-1);
}
waitloop(2000);
//wait for transmitter to be ready then send the register address
//SEND DATA BYTES
for(i=0;i<regLen;i++){
//get the current byte
tempByte = RegAddr[i];
//wait for transmitter to be ready then send the upper byte of data
while(I2C_REG0->ICSTR.bit.ICXRDY == 0);
I2C_REG0->ICDXR.bit.D = tempByte;
//wait for data to go out
waitloop(4000);
//check for a NACK
if(I2C_REG0->ICSTR.bit.NACK){
I2C_REG0->ICMDR.bit.STP = 1;
return(-1);
}
}
}
/****************************/
//setup device for read
/****************************/
//now set up to receive the upper byte of data
I2C_REG0->ICMDR.bit.MST = 1; //make sure we're in master mode
I2C_REG0->ICMDR.bit.TRX = 0; //make sure we're in receive mode
I2C_REG0->ICMDR.bit.NACKMOD = 0; //send NACK at end
I2C_REG0->ICCNT.bit.ICDC = 0; //
//set up the slave address
I2C_REG0->ICSAR.bit.SADDR = deviceAddr >> 1;
//send the START condition and the slave address
I2C_REG0->ICMDR.bit.STT = 1;
waitloop(10000);
//check for a NACK
if(I2C_REG0->ICSTR.bit.NACK){
I2C_REG0->ICMDR.bit.STP = 1;
return(-1);
}
//Loop through and collect reads
for(i=0;i<dataLen;i++){
if(i==dataLen - 1){
I2C_REG0->ICMDR.bit.NACKMOD = 1;
}
waitloop(10000);
//wait for byte to show up in recieve buffer
while(I2C_REG0->ICSTR.bit.ICRRDY == 0);
data[dataLen-1-i] = I2C_REG0->ICDRR.bit.D;
}
I2C_REG0->ICMDR.bit.STP = 1;
}