功能描述:
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信号产生?