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();        //I2C初始化

         IniInterrupt();

         ReadParameters();  //读取数据

         for(;;)
         {
             SaveParameters();     //保存数据
         }

}

  //I2C初始化函数

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 ) //与设计值不符,重新写EEPROM数据
{
index = 0U;
funcpointer = (FuncBits *)&Funcode;

//写16位数据

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++;
}

//写32位数据,分两次写,一次写16位

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;
}
}

}

//I2C初始化函数

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)