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.

[参考译文] TMS320F2.8027万:I2C EEPROM读取

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/618261/tms320f28027-i2c-eeprom-read

部件号:TMS320F2.8027万

您好,

我需要使用串行I2C EEPROM。 我的MCU是TMS320F2.8027万。

我有点失望,因为许多关于相同主题的帖子对我没有帮助。

我更喜欢没有中断的版本(简单性,线性函数,更适合bootloader)。

控制套件中的中断示例也使用FIFO。 它在超过3个数据字节(FIFO深度4字节)的情况下不起作用,并且它正在总线上重复发送某些内容。

我找到的最好的代码是 e2e.ti.com/.../3806.5126.I2C_5F00_Writing_5F00_Reading_5F00_EEPROM.txt引用的fom

我在使用时做了一些小的修改(1字节地址,在函数末尾设置了STP)。

void I2C_READ (UINT16 Slaver_address,UINT16 Start_address,UINT16 No_of_databytes,UINT16 READ_Array[])
{////////////////////////////////////
	
	//从EEPROM/////////////////////////////////读取数据
	
	I2caRegs.I2CSAR = Slaver_address;			//设置从属地址
	I2caRegs.I2CCNT = 1;						//设置计数为2个地址字节
	I2caRegs.I2CDXR = Start_address;			//MST EEPROM高地址
	I2caRegs.I2CMDR.Bit.TRX = 1;				//设置为传输模式I2caReg.I21.Ibit.IDM.I1.
					
					
					//不在Tx
	I2caRegs.I2CMDR.bit.STT =1后释放总线;				//发送起始位,传输将跟随

	I2caRegs.I2CSTR.bit.XRDY ==0){};		//不执行任何操作,直到数据移出
//	I2caRegs.I2CDXR = Start_I2CR=0=0			
					;EEPROM_ICAREADDR.0=0;EP.ICA.DBY = 0
					//设置为接收模式
	I2caRegs.I2CMDR.bit.MST = 1;				//设置为主模式
	I2caRegs.I2CMDR.bit.free = 1;				//在空闲模式下运行
					//当内部计数器变为0
	I2caRegs.I2CMDR.bit.STT = 1;//重复启动,
	
	RDC= I2R=未准备就绪;I2R= I2R=
			
		READ_Array[I]= I2caRegs.I2CDRR;
	}
	I2caRegs.I2CMDR.bit.STP =1;
}

当我在一个序列中读取两次4字节时,我得到两个不同的读数。 第一个调用将读取另一个字节。

   I2C_READ (0x50,0xFD,3,READ_Array);

   I2C_READ (0x50,0xFD,3,READ_Array2);

因此,我从第一个读数获得{0x10,0x00,0xEF},从第二个读数获得{0xA,0a10,0x00}。

{0xEF,0a10,0x00}从第三个读数开始。

因此读数会发生变化。

是否有人知道什么可能是错误的?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Lukas:

    从您的波形看,EEPROM似乎认为它需要发送比您所指示的更多的字节,并且没有发送停止条件(但很难看到足够清楚的波形来判断)。

    我认为这是您问题的解决方案,但您必须对其进行测试以确认...

    将I2caRegs.I2CMDR.bit.stp设置为1时,当I2C模块的内部数据计数器倒计数为0时,设备将生成停止条件。

    内部数据计数器的工作方式如下:

    1.您写入I2CCNT的值将被复制到内部计数器
    2.对于每个传输的字节,计数器将递减1,直到达到0
    3.如果在主模式下请求停止条件,则在倒计时完成后,传输将以停止条件终止(内部数据计数器达到0)

    所以我认为你应该尝试将I2caRegs.I2CCNT设置为(No_of_databytes -1)以允许内部计数器达到零。

    希望这能有所帮助,
    Kevin
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Kevin:
    非常感谢您的回答。
    很遗憾,我不同意你的说法。
    A/ EEPROM认为它不必发送更多。 它仅在SCL运行时发送。 所以它在MCU的控制下。

    b/重要的事实是,在第一次运行期间,传输4个数据字节而不是3个。 在第二次运行期间,正确的3个字节将按预期传输,但从缓冲区读取的数据将被转移。 我可以尝试,但我认为I2CCNT设置为No_of_databytes -1只会在每行传输1个字节。

    EEPROM为24LC02B。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Lukas:

    你可能是对的。 如果I2CCNT等于(No_of_databytes -1)导致在第一次运行时传输3个字节,在第二次运行时传输2个字节,我不会感到惊讶,但我认为最好是测试一下到底发生了什么。

    要澄清,第一组字节是{0x10, 0x00, 0xEF},第二组是{0x0A, 0x10, 0x00}? 如果是这样,则第一个读取中多余的0x0A字节似乎正在被滚动到第二组被读取的字节。 您同意吗?

    从您的波形中,我看到在首次读取的额外字节(字节4)后生成一个nack。 在主接收器模式和非重复模式(即I2CMDR中的RM = 0,这是默认值)中,可以通过以下方式生成nack:

    •如果I2CMDR中的STP = 1,则允许内部数据计数器倒计时至0,从而强制执行停止条件
    •如果STP =0,则使STP =1生成停止条件
    •重置模块(I2CMDR中的IRS = 0)。 = 1以生成停止条件
    •将I2CMDR的NACKMOD位设置在您要接收的最后一个数据位的上升边缘之前

    这个列表的第一点让我觉得它与内部数据计数器有关。 您可以尝试将I2caRegs.I2CMDR.bit.stp = 1;移入for循环(甚至之前),因为在内部倒计时完成之前不会生成停止条件。

    编辑:有关详细信息,请参阅TMS320x2802x,2803x Piccolo Inter-Integrated Circuit (I2C)模块参考指南。

    www.ti.com/.../sprufz9d.pdf

    希望这能有所帮助,
    Kevin

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Kevin:
    谢谢你。
    遗憾的是,它没有帮助。
    在波形中,nack可能倒计数为0,但这似乎发生得太晚。
    我会尝试其他东西。
    当I2caRegs.I2CMDR.bit.stp =1之前使用时,仅传输两个字节,第二个函数调用挂起,而(I2caRegs.I2CSTR.bit.XRDY ==0){);.

    Lukas
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Lukas:

    很抱歉,这不起作用。 是的,我觉得奇怪的是,nack延迟了1个字节,而且在此之前没有生成停止条件。

    因此,如果将I2caRegs.I2CMDR.bit.stp =1设置为提前且No_of_databytes =3设置为首次调用,则只接收两个字节? 第二个字节后是否立即生成nack?

    最佳,
    Kevin