This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320DM643:通过 I2C 接收数据时出现问题

Guru**** 1712740 points
Other Parts Discussed in Thread: TMS320DM643, TMS320DM6437
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1059134/tms320dm643-problems-receiving-data-through-i2c

器件型号:TMS320DM643

大家好、

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

}