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.

[参考译文] CCS/LAUNCHXL-F28069M:与24C04进行 I2C 通信

Guru**** 2612025 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/692433/ccs-launchxl-f28069m-i2c-communication-with-24c04

器件型号:LAUNCHXL-F28069M

工具/软件:Code Composer Studio

大家好、

24c04 EEPROM 数据表为:  

我测试的代码如下:

如果(t<10)
{
WriteEeprom (t、10+t);
WriteEeprom (t+1、10+t+1);

DataRad[t]= ReadEeprom (t);
//DataRad[t+1]=(ReadEeprom (t+1)<<8)| DataRad[t];
DataRad[t+1]= ReadEeprom (t+1);

T=t+2;
}

如果(t>=10)
{} 
void I2CA_Init (void)
{
I2caRegs.I2CMDR.ALL = 0x0000;
//初始化 I2C
I2caRegs.I2CSAR = 0x0050; //从机地址—EEPROM 控制代码

// I2CCLK = SYSCLK/(I2CPSC+1)

I2caRegs.I2CPSC.all = 8;//6 //预分频器-模块时钟需要7-12MHz


I2caRegs.I2CCLKL = 10; //注:必须为非零
I2caRegs.I2CCLKH=5; //注:必须为非零
// I2caRegs.I2CIER.ALL = 0x24; //启用 SCD 和 ARDY 中断

I2caRegs.I2CMDR.ALL = 0x0020;//使 I2C 退出复位
//挂起时停止 I2C

I2caRegs.I2CFFTX.ALL = 0x6000;//启用 FIFO 模式和 TXFIFO
I2caRegs.I2CFFRX.ALL = 0x2040;//启用 RXFIFO、清除 RXFFINT、

返回;
} 
UINT16 ReadEeprom (UINT16 e2promaddress)
{
uint16地址慢速;
uint16地址;


I2caRegs.I2CMDR.bit.IRS = 1; //复位 I2C
while (I2cRegs.I2CSTR.bit.BB = 1); //忙循环
I2caRegs.I2CSTR.bit.SCD = 1; //清除 SCD 位(停止条件位)
while (I2caRegs.I2CMDR.bit.STP==1); //停止位循环

地址 = e2promaddress>>8;
寻址 = e2promaddress;
I2caRegs.I2CSAR = 0x0050;

while (I2cRegs.I2CSTR.bit.BB = 1);
I2caRegs.I2CMDR.ALL = 0x2620; //开始、无停止位、主器件、TX、复位 I2C
I2caRegs.I2CCNT = 0x0002;
I2caRegs.I2CDXR =地址高;
I2caRegs.I2CDXR =地址慢速;
while (!I2cRegs.I2CSTR.bit.ARDY); //准备好了吗?

I2caRegs.I2CMDR.ALL = 0x2C20; //开始、CNT = 0时的停止位、主器件、Rx、复位 I2C
I2caRegs.I2CCNT = 1;

if (I2caRegs.I2CSTR.bit.nack = 1)
{
I2caRegs.I2CSTR.All = I2C_CLR_Nack_bit;// 0x0002
}
I2caRegs.I2CMDR.bit.STP= 1; // CNT=0时停止位

while (!I2cRegs.I2CSTR.bit.SCD); //是否检测到停止位?

// tempdata = I2caRegs.I2CDRR << 8; //读取数据
tempdata = I2caRegs.I2CDRR;
totalTemp = tempdata + totalTemp;

DELAY_US (100);

return (tempdata);
} 

void WriteEeprom (uint16 e2promaddress、uint16 data)
{
uint16地址慢速;
uint16地址;
uint16 testval=3;
I2caRegs.I2CMDR.bit.IRS = 1; //复位 I2C

地址 =(e2promaddress>>8)&0x00FF;
寻址 = e2promaddress&0x00FF;
I2caRegs.I2CSAR = 0x0050; // EEPROM 控制位+地址(A0-A2)。 对于24LC256、0 1 0 1 0 A0 A1 A2

while (I2cRegs.I2CSTR.bit.BB = 1);

I2caRegs.I2CCNT = 3;
I2caRegs.I2CMDR.ALL = 0x6E20; //start、stop、no rm、reset i2c
I2caRegs.I2CDXR =地址高;
I2caRegs.I2CDXR =地址慢速;

//I2caRegs.I2CDXR =(testval >> 8)和0x00FF;//高字节数据
I2caRegs.I2CDXR = testval; //低字节数据
wtempdata = I2caRegs.I2CDXR;

I2caRegs.I2CMDR.bit.STP= 1; // CNT=0时停止位

while (!I2cRegs.I2CSTR.bit.SCD); //是否检测到停止位?

DELAY_US (5000); // 5ms = 24LC256的写入周期时间-基于数据表24LC256

返回;
} 

首先、我将"3"值写入10个地址(t<10)。 然后更改了代码并希望读取20个地址。 他们都是“3”。 然后、我想知道在哪个 EEPROM 地址之前、该值是"3"、它是255 (t<256)。

“totalTemp”下面是3*256,这意味着24c04中的256个地址被定义为“3”。  

这是正常行为吗? 我不熟悉 EEPROM 通信、无法了解原因。  

谢谢你。

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

    特罗东

    从 I2C 配置的角度来看、我没有发现您所做的事情有什么问题。 从 EEPROM 的角度来看、我不确定。 大多数 EEPROM 都具有分页写入。 确保您没有执行分页写操作。

    此致、

    曼诺伊

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

    Manoj、您好!

    感谢您的回答。

    我添加了该器件以检查正在发生的情况。

    UINT16 T1 = 0;
    UINT16 T2 = 0;
    UINT16地址 Val = 0;
    UINT16数据 Val = 0; 

    for (;;)
    {
    
    如果(T1<1)
    {
    WriteEeprom (addressVal、dataVal);
    t1=t1+1;
    }
    如果(T2<4)
    {
    ReadEeprom (addressVal);
    t2=t2+1;
    }
    } 

    我还需要  检查 dataReadSample[300]和 dataWriteSample[20]。

    无论如何、

    T1是写入函数的重复时间、T2是读取函数的重复时间。

    当我写入 EEPROM 1次并从 EEPROM 读取4次时、一切工作都很完美。

    --------------------------------------------------------------------

    否则、

    如果我读取 dataReadSample[99] 1次、其旧值不会改变。

    第二次,没有变化。

    第三次、我读取0值。

    第4次、我读取了正确的值。

    --------------------------------------------------------------------

    当我重试时:

    第一次:我读取的值是43

    第二次:173.

    第三次:0

    4时间:正确的结果。

    --------------------------------------------------------------------

    我已经使用24c04、24c02、24lc256进行了测试、但行为是相同的。

    写法和读法没有什么问题。 我觉得有时间问题、阅读晚了等  

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

    我想知道、您是否需要等待足够长的 EEPROM 来写入正确的值。 您可能会在写入操作的中间读取 EEPROM。

    您能否在每次 EEPROM 写入操作后添加延迟功能(等待取决于 EEPROM DS)? 我希望它很可能会解决您的问题。

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

    原因不是缺少延迟、因为我手动操作写入和读取命令。 此外,我还有 函数:

    DELAY_US (5000);// 5ms = 24LC256的写入周期时间-基于数据表24LC256 

    但我发现了我的错误。

    UINT16 ReadEeprom (UINT16 e2promaddress)
    {
    uint16地址慢速;
    uint16地址;
    
    
    I2caRegs.I2CMDR.bit.IRS = 1; //复位 I2C
    while (I2cRegs.I2CSTR.bit.BB = 1); //忙循环
    I2caRegs.I2CSTR.bit.SCD = 1; //清除 SCD 位(停止条件位)
    while (I2caRegs.I2CMDR.bit.STP==1); //停止位循环
    
    地址 = e2promaddress>>8;
    寻址 = e2promaddress;
    
    I2caRegs.I2CSAR = 0x0050;
    
    while (I2cRegs.I2CSTR.bit.BB = 1);
    I2caRegs.I2CMDR.ALL = 0x2620; //开始、无停止位、主器件、TX、复位 I2C
    I2caRegs.I2CCNT = 0x0002;
    I2caRegs.I2CDXR =地址高;
    I2caRegs.I2CDXR =地址慢速;
    
    while (!I2cRegs.I2CSTR.bit.ARDY); //准备好了吗?
    
    I2caRegs.I2CMDR.ALL = 0x2C20; //开始、CNT = 0时的停止位、主器件、Rx、复位 I2C
    I2caRegs.I2CCNT = 1;
    
    if (I2caRegs.I2CSTR.bit.nack = 1)
    {
    I2caRegs.I2CSTR.All = I2C_CLR_Nack_bit;// 0x0002
    }
    I2caRegs.I2CMDR.bit.STP= 1; // CNT=0时停止位
    
    while (!I2cRegs.I2CSTR.bit.SCD); //是否检测到停止位?
    
    // tempdata = I2caRegs.I2CDRR << 8; //读取数据
    tempdata = I2caRegs.I2CDRR;
    dataReadSamply[e2promaddress]= I2caRegs.I2CDRR;
    totalTemp = tempdata + totalTemp;
    
    DELAY_US (100);
    
    return (tempdata);
    } 

    ReadEeprom 子例程如上所示。

    tempdata = I2caRegs.I2CDRR;
    dataReadSample[e2promaddress]= I2caRegs.I2CDRR; 

    这个部件是问题。 为了读取 dataReadSample、我第二次调用 I2caRegs.I2CDRR、但不删除"tempdata = I2caRegs.I2CDRr";

    //tempdata = I2cares.I2CDRR;
    dataReadSample[e2promaddress]= I2cares.I2CDRR; 

    所以大家不要多次说"I2caRegs.I2CDRR"。 )