大家好、
我们有一个旧设计、在该设计中、我们曾将数据读取为 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; }