TI中文支持网
TI专业的中文技术问题搜集分享网站

F28034 I2C读写EEPROM数据错误的问题

功能描述:

1)读写方式:使用F28034的I2C引脚,硬件电路如下

2)读写逻辑:从EEPROM(ATMLH54432DM)中读取数据,如果数据与条件不符,则重新写入所有数据(包括16位及32位数据);否则,只读取EEPROM中数据

3)数据可实时保存至EEPROM

问题描述:

1、第一次下载程序后,从EEPROM读取的部分数据值错误,设计值为0,但读取为65535(0xFFFF)

2、第一次下载程序后,数据无误,但多次断电重启后,出现1中错误

3、数据无法实时保存,但在保存指令发出时,监测到SDA、SCL均有脉冲信号

请大神帮忙看下是否代码原因或是其他

代码:

1、I2C部分代码参照TI例程“i2c_eeprom”

2、

void main(void)
{

         InitSysCtrl();

         I2C_Init();

         IniInterrupt();

         ReadParameters();

         for(;;)
         {
             SaveParameters();
         }

}

void I2C_Init(void)
{
// Initialize I2C
I2caRegs.I2CSAR = 0x0050; // Slave address – EEPROM control code

I2caRegs.I2CPSC.all = 6; // Prescaler – need 7-12 Mhz on module clk
I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
I2caRegs.I2CCLKH = 5; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts

I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
// Stop I2C when suspended

I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,

return;

}

ReadParameters()

{

uint index;
uint index1;
unsigned int ReadData=0,ReadData1=0,ReadData2=0;
unsigned int ReData1=0,ReData2=0;
unnRWEepr.bit.ReadOK = 0;
RwiicCnt = 0;

RxStatus = I2C_MSGSTAT_SEND_NOSTOP;
pStatus = &RxStatus;
while( (!unnRWEepr.bit.ReadOK) && (RwiicCnt<RWCNT) )
{
ReadRx(FSoftWareVer * 2);
Delay_us(15);
DetectRW();

RwiicCnt++;
}
unnRWEepr.bit.ReadOK = 0;
RwiicCnt = 0;
ReadData = Paraall;

if(  ReadData != SOFTWARE )
{
index = 0U;
funcpointer = (FuncBits *)&Funcode;

while(index < sizeof(OrgValue) / sizeof(Funcode.Udc.value)) {

TxStatus = I2C_MSGSTAT_SEND_WITHSTOP;
RxStatus = I2C_MSGSTAT_SEND_NOSTOP;
pStatus = &TxStatus;

while( (!unnRWEepr.bit.ReadOK) && (RwiicCnt<RWCNT) )
{
WriteTx(index << 1U, OrgValue[index]);
Delay_us(30);
DetectRW();

RwiicCnt++;
}
unnRWEepr.bit.ReadOK = 0;
RwiicCnt = 0;

funcpointer->value = OrgValue[index];
funcpointer++;
index++;
}

longfuncpointer =(uint32 *) &ValueLong; for(index1 = 0U; index1 < sizeof(Need32) / sizeof(Funcode.Udc.value) -1; index1++) {

TxStatus = I2C_MSGSTAT_SEND_WITHSTOP;
RxStatus = I2C_MSGSTAT_SEND_NOSTOP;
pStatus = &TxStatus;
while( (!unnRWEepr.bit.ReadOK) && (RwiicCnt<RWCNT) )
{
WriteTx(index << 1U, 0);
Delay_us(30);
DetectRW();

RwiicCnt++;
}
unnRWEepr.bit.ReadOK = 0;
RwiicCnt = 0;

TxStatus = I2C_MSGSTAT_SEND_WITHSTOP;
RxStatus = I2C_MSGSTAT_SEND_NOSTOP;
pStatus = &TxStatus;
while( (!unnRWEepr.bit.ReadOK) && (RwiicCnt<RWCNT) )
{
WriteTx((index << 1U) + 2U, OrgValue[(int16_T)Need32[(int16_T)(index1 + 1U)]]);
Delay_us(30);
DetectRW();

RwiicCnt++;
} unnRWEepr.bit.ReadOK = 0;
RwiicCnt = 0;
*longfuncpointer = OrgValue[(int16_T)Need32[(int16_T)(index1 + 1U)]];
longfuncpointer++;
index += 2U;
}
} else {
index = 0U;
funcpointer = (FuncBits *)&Funcode; while(index < sizeof(Funcode) / sizeof(Funcode.Udc)) {
RxStatus = I2C_MSGSTAT_SEND_NOSTOP;
pStatus = &RxStatus;

while( (!unnRWEepr.bit.ReadOK) && (RwiicCnt<RWCNT) )
{
ReadRx(index << 1U);
Delay_us(30);
DetectRW();

RwiicCnt++;
}
unnRWEepr.bit.ReadOK = 0;
RwiicCnt = 0;
ReadData = Paraall;
funcpointer->value = ReadData;
funcpointer++;
index++;
}

longfuncpointer =(uint32 *) &ValueLong; for(index1 = 0U; index1 < sizeof(ValueLong) / sizeof(ValueLong.IdNumber);index1++) {
RxStatus = I2C_MSGSTAT_SEND_NOSTOP;
pStatus = &RxStatus;

while( (!unnRWEepr.bit.ReadOK) && (RwiicCnt<RWCNT) )
{
ReadRx(index << 1U);
Delay_us(30);
DetectRW();

RwiicCnt++;
}
unnRWEepr.bit.ReadOK = 0;
RwiicCnt = 0;
ReadData1 = Paraall;
RxStatus = I2C_MSGSTAT_SEND_NOSTOP;
pStatus = &RxStatus;

while( (!unnRWEepr.bit.ReadOK) && (RwiicCnt<RWCNT) )
{
ReadRx( (index <<1U ) + 2U );
Delay_us(30);
DetectRW();

RwiicCnt++;
}
unnRWEepr.bit.ReadOK = 0;
RwiicCnt = 0;
ReadData2 = Paraall;

*longfuncpointer = ReadData1 * 65536L + ReadData2;
longfuncpointer++;
index += 2U;
}
}

}

unsigned int ReadEeprom(unsigned int Address){ unsigned int _address;
// Wait until the STP bit is cleared from any previous master communication.
// Clearing of this bit by the module is delayed until after the SCD bit is
// set. If this bit is not checked prior to initiating a new message, the
// I2C could get confused.
_address = Address;
if (I2caRegs.I2CMDR.bit.STP == 1)
{
return I2C_STP_NOT_READY_ERROR;
}

I2caRegs.I2CSAR = I2C_SLAVE_ADDR;

if( RxStatus == I2C_MSGSTAT_SEND_NOSTOP )
{
// Check if bus busy /*
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
*/
I2caRegs.I2CCNT = 2;
I2caRegs.I2CDXR = (_address>>8) & 0x00ff;
I2caRegs.I2CDXR = Address & 0x00ff;
I2caRegs.I2CMDR.all = 0x2620; // Send data to setup EEPROM address
}
else if( RxStatus == I2C_MSGSTAT_RESTART )
//I2caRegs.I2CSTR.bit.SCD = 1; // 清除该位,否则连续读时会在while SCD时等待
{

I2caRegs.I2CCNT = I2C_NUMBYTES; //设置要接收的数据个数
I2caRegs.I2CMDR.all = 0x2C20;// Send restart as master receiver
//Reading EEPROM data completed, read data from FIFO. }

return I2C_SUCCESS;}unsigned int WriteEeprom(unsigned int Address,unsigned int Para){//Uint16 i;
unsigned short _Para=0;
unsigned int _address;

_address = Address;
_Para = Para & 0x0000ffff;
// Wait until the STP bit is cleared from any previous master communication.
// Clearing of this bit by the module is delayed until after the SCD bit is
// set. If this bit is not checked prior to initiating a new message, the
// I2C could get confused.

if (I2caRegs.I2CMDR.bit.STP == 1)
{
return I2C_STP_NOT_READY_ERROR;
}

// Setup slave address I2caRegs.I2CSAR = I2C_SLAVE_ADDR;

// Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}

// Setup number of bytes to send
// MsgBuffer + Address
I2caRegs.I2CCNT = I2C_NUMBYTES+2; //发送数据的字节数,
//WordAddress+ NumOfBytes (Slave Address不包括在内)

// Setup data to send
I2caRegs.I2CDXR = (_address>>8) & 0x00ff;
I2caRegs.I2CDXR = Address & 0x00ff;
//for( i=0; i<I2C_NUMBYTES; i++ )
{
I2caRegs.I2CDXR = _Para;
I2caRegs.I2CDXR = _Para>>8;
}

// Send start as master transmitter
I2caRegs.I2CMDR.all = 0x6E20;

return I2C_SUCCESS;}

void ReadRx(unsigned int Address)
{
// Uint16 Error;

if(RxStatus == I2C_MSGSTAT_SEND_NOSTOP)
{
while( ReadEeprom(Address) != I2C_SUCCESS );
//Error = ReadEeprom(Address);
//if(Error == I2C_SUCCESS)
{
pStatus = &RxStatus;
RxStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY;
}
}
else if(RxStatus == I2C_MSGSTAT_RESTART )
{
while( ReadEeprom(Address) != I2C_SUCCESS );
//Error = ReadEeprom(Address);
//if(Error == I2C_SUCCESS)
{
pStatus = &RxStatus;
RxStatus = I2C_MSGSTAT_READ_BUSY; }
}
}
void WriteTx(unsigned int Address,unsigned int Para)
{
Uint16 Error;
/* if( TxStatus==I2C_MSGSTAT_SEND_WITHSTOP )
{
Error = WriteEeprom(Address,Para);
if( Error == I2C_SUCCESS )
{
pStatus = &TxStatus;
TxStatus = I2C_MSGSTAT_WRITE_BUSY;
}
}
if( TxStatus == I2C_MSGSTAT_INACTIVE )
{
unnRWEepr.bit.WriteOK = 1;
RxStatus = I2C_MSGSTAT_SEND_NOSTOP; }
*/
if( TxStatus==I2C_MSGSTAT_SEND_WITHSTOP )
{
Error = WriteEeprom(Address,Para);
if( Error == I2C_SUCCESS )
{
pStatus = &TxStatus;
TxStatus = I2C_MSGSTAT_WRITE_BUSY;
}
}

if( TxStatus == I2C_MSGSTAT_INACTIVE )
{
if(RxStatus == I2C_MSGSTAT_SEND_NOSTOP)
{
while( ReadEeprom(Address) != I2C_SUCCESS );
pStatus = &RxStatus;
RxStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY;
}
else if(RxStatus == I2C_MSGSTAT_RESTART )
{
while( ReadEeprom(Address) != I2C_SUCCESS );
pStatus = &RxStatus;
RxStatus = I2C_MSGSTAT_READ_BUSY; }
}

}

void DetectRW()
{
//Uint16 i;
unsigned int Parah=0,Paral=0;
Uint16 IntSource;

IntSource = I2caRegs.I2CISRC.all;
if( IntSource == I2C_SCD_ISRC )
{
if( *pStatus == I2C_MSGSTAT_WRITE_BUSY )
{
*pStatus = I2C_MSGSTAT_INACTIVE;
}
else
{
if( *pStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY )
*pStatus = I2C_MSGSTAT_SEND_NOSTOP;
else if( *pStatus == I2C_MSGSTAT_READ_BUSY )
{
*pStatus = I2C_MSGSTAT_INACTIVE;
/*
for(i=0; i < I2C_NUMBYTES; i++)
tBuffer[i] = I2caRegs.I2CDRR;
*/
Paral=I2caRegs.I2CDRR;
Parah=I2caRegs.I2CDRR;
Paraall= Paral | (Parah << 8);

unnRWEepr.bit.ReadOK = 1;
}
}
}
else if( IntSource == I2C_ARDY_ISRC )
{
if(I2caRegs.I2CSTR.bit.NACK == 1)
{
I2caRegs.I2CMDR.bit.STP = 1;
I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
}
else if(*pStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)
{
*pStatus = I2C_MSGSTAT_RESTART;
}
}

}

void I2C_Init(void)
{
// Initialize I2C
I2caRegs.I2CSAR = 0x0050; // Slave address – EEPROM control code

I2caRegs.I2CPSC.all = 6; // Prescaler – need 7-12 Mhz on module clk
I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
I2caRegs.I2CCLKH = 5; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts

I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
// Stop I2C when suspended

I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,

return;

}

Johnson Chen1:

是否有注意到EEPROM 页大小和 F2803x FIFO 大小问题?从时序上看是否有ACK信号产生?

赞(0)
未经允许不得转载:TI中文支持网 » F28034 I2C读写EEPROM数据错误的问题
分享到: 更多 (0)