请教一个CRC校验的问题。

hjiongh 2009-03-20 01:38:16
我现在要测试eeprom, 24LC256

我全写,用页写方式,每页64bytes,一共32k bytes,所以是512页。

我用CRC16_CCITT方式校验。

现在是这样测试的:我全写0xaa, 每写一页,然后对64个bytes进行crc,然后进行第二页写,第二页的crc校验时以第一页校验值为初始值,这样,连续512页写入,等于是32k bytes连续校验,最后得到一个CRC值。记录下这个CRC值。

然后再写全部read whole eeprom。 也是通过上面方式,进行一个CRC值校验。 记录下这个CRC值。

两个CRC值作比较,我发现当我写300页的时候,一样,但是我写512页的时候却得到的值不一样。

是不是我的EEPROM片子有某些页坏了?

还是这个EEPROM有某些页有特殊处理?
...全文
178 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
hjiongh 2009-03-23
  • 打赏
  • 举报
回复
测试24lc256的代码 ,

void main(void)
{
... ...
PRO_WRITE_EEPROM_ALL_PAGES(PRO_I2C_1, PRO_I2C_SPEED_400K);
PRO_READ_EEPROM_ALL_PAGES(PRO_I2C_1, PRO_I2C_SPEED_400K);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
INT32U PRO_EEPROM_WritePages(PRO_I2C_tModule i2c_tMod, INT32U add, INT8U* pbuf, INT32U len, INT32U* pErrCode)
{
INT32U status = 0;
INT32U iAdr = add;
INT8U *padr;
INT32U iLen = len;
INT8U high_addr,low_addr;
*pErrCode = EEPROM_ERROR_NONE;

EEPROM_WP_HI();

padr = pbuf;

low_addr = (INT8U)(iAdr & 0x00ff);
high_addr = (INT8U)((iAdr & 0xff00) >> 8);

status = PRO_I2C_WritePages(i2c_tMod, padr, iLen, high_addr, low_addr);

return status;

}

void PRO_EEPROM_ReadBytes(PRO_I2C_tModule i2c_tMod, INT16U add, BYTE *pbuf, INT32U len, INT32U* pErrCode)
{
INT32U status = 0;
INT32U iAdr = add;
INT8U *padr = pbuf;
INT32U iLen = len;
INT8U high_addr,low_addr;
*pErrCode = EEPROM_ERROR_NONE;


while (iLen > 0)
{

low_addr = (INT8U)(iAdr & 0x00ff);
high_addr = (INT8U)((iAdr & 0xff00) >> 8);

*padr = PRO_I2C_ReadByte(i2c_tMod, high_addr, low_addr);

//PRO_TmrDelay(0xfff); // about 68us

iLen--;
padr++;
iAdr++;

}

return;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
INT32U PRO_WRITE_EEPROM_ALL_PAGES(PRO_I2C_tModule i2c_tMod, PRO_I2C_tSpeed i2c_tSpeed)
{
BYTE EEPROM_Tx_Buffer[512][64];
INT32U i,j,flag;
INT32U addr;
INT32U errcode = 0;
INT16U crc_reg = 0xffff;

PRO_EEPROM_Initialize(i2c_tMod, i2c_tSpeed);
// first ,write whole eeprom
for (i=0; i<EEPROM_PAGE_NUM; i++)
{
addr = (INT32U)(ADDR_PAGE_0 + (i*EEPROM_PAGE_SIZE));
for (j=0; j<EEPROM_PAGE_SIZE; j++)
{
EEPROM_Tx_Buffer[i][j] = (INT8U)(0x55);
}

crc_reg = CRC_CheckCRC16_CCITT(EEPROM_Tx_Buffer[i], EEPROM_PAGE_SIZE , crc_reg);

PRO_EEPROM_WritePages(i2c_tMod, addr, EEPROM_Tx_Buffer[i], EEPROM_PAGE_SIZE, &errcode);
PRO_Ticker_DelayMs(1, 5);

}

return;
}

INT32U PRO_READ_EEPROM_ALL_PAGES(PRO_I2C_tModule i2c_tMod, PRO_I2C_tSpeed i2c_tSpeed)
{
BYTE EEPROM_Rx_Buffer[512][64];
INT32U i,j,flag;
INT32U addr;
INT32U errcode = 0;
INT16U crc_reg = 0xffff;
INT32U count = 0;

j = 0;

PRO_EEPROM_Initialize(i2c_tMod, i2c_tSpeed);
// read whole eeprom
for (i=0; i<EEPROM_PAGE_NUM; i++)
{
addr = (INT32U)(ADDR_PAGE_0 + (i*EEPROM_PAGE_SIZE));
PRO_EEPROM_ReadBytes(i2c_tMod, addr, EEPROM_Rx_Buffer[i], EEPROM_PAGE_SIZE, &errcode);

crc_reg = CRC_CheckCRC16_CCITT(EEPROM_Rx_Buffer[i], EEPROM_PAGE_SIZE , crc_reg);

for(j=0; j<EEPROM_PAGE_SIZE; j++)
{
if(EEPROM_Rx_Buffer[i][j] != 0x55)
{
count++;
}
}
}

return;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
PRO_I2C_tStatus PRO_I2C_WriteByte(int logI2C, BYTE data, BYTE highaddress, BYTE lowaddress)
{
PRO_I2C_tpRegister pReg;
int physI2C;
const PRO_I2C_tI2CTblEntry *pConfTab;

// Check for valid logUART number and valid configuration values
if ((logI2C < 0) || (logI2C >= NUM_OF_LOG_I2CS))
{
return PRO_I2C_INVALID_NUMBER;
}

pConfTab = &LogConfigTable[logI2C];
physI2C = pConfTab->physI2C;
pReg = PhysADRLookup[physI2C];

LogPhysicalRegs[logI2C] = pReg;
PhysLogicalI2C[physI2C] = logI2C;

pReg[I2C_CONCLR] = (I2CONCLR_STAC|I2CONCLR_SIC|I2CONCLR_AAC);
pReg[I2C_CONSET] = I2CONSET_I2EN; //enable I2C as master
pReg[I2C_CONSET] = I2CONSET_STA; //send start condition

while(pReg[I2C_STAT] != 0x8);
pReg[I2C_DAT] = 0xA0; //set SLA+W:1010000+0
pReg[I2C_CONCLR] = (I2CONCLR_SIC|I2CONCLR_STAC); //clear SI bit to transmit SLA+W

while(pReg[I2C_STAT] != 0x18);
pReg[I2C_DAT] = highaddress; //write address to eeprom
pReg[I2C_CONCLR] = I2CONCLR_SIC; //clear SI bit to transmit address

while(pReg[I2C_STAT] != 0x28);
pReg[I2C_DAT] = lowaddress; //write address to eeprom
pReg[I2C_CONCLR] = I2CONCLR_SIC; //clear SI bit to transmit address

while(pReg[I2C_STAT] != 0x28); //stat must be 0x28
pReg[I2C_DAT] = data; //write data to eeprom
pReg[I2C_CONCLR] = I2CONCLR_SIC; //clear SI bit to transmit data

//PRO_Ticker_DelayMs(1,1); //wait to send data to eeprom
while(pReg[I2C_STAT] != 0x28); //stat must be 0x28
pReg[I2C_CONCLR] = I2CONCLR_SIC;
pReg[I2C_CONSET] = I2CONSET_STO; //set STO bit to stop transmit

PRO_Ticker_DelayMs(1,3);

return PRO_I2C_OK;
}

BYTE PRO_I2C_ReadByte(int logI2C, BYTE highaddress, BYTE lowaddress)
{
BYTE data;
PRO_I2C_tpRegister pReg;
int physI2C;
const PRO_I2C_tI2CTblEntry *pConfTab;

// Check for valid logUART number and valid configuration values
if ((logI2C < 0) || (logI2C >= NUM_OF_LOG_I2CS))
{
return PRO_I2C_INVALID_NUMBER;
}

pConfTab = &LogConfigTable[logI2C];
physI2C = pConfTab->physI2C;
pReg = PhysADRLookup[physI2C];

LogPhysicalRegs[logI2C] = pReg;
PhysLogicalI2C[physI2C] = logI2C;



pReg[I2C_CONCLR] = (I2CONCLR_STAC|I2CONCLR_SIC|I2CONCLR_AAC);
pReg[I2C_CONSET] = I2CONSET_I2EN; //enable I2C as master

pReg[I2C_CONSET] = I2CONSET_STA; //send a start condition
pReg[I2C_CONSET] = I2CONSET_STA; //test restart!!

while(pReg[I2C_STAT] != 0x8);//state word must be 0x8
pReg[I2C_DAT] = 0xA0;//set SLA+W
pReg[I2C_CONCLR] = 0x8|0x20;//clear SI bit to transmit SLA+W

while(pReg[I2C_STAT] != 0x18);//state word must be 0x18
pReg[I2C_DAT] = highaddress;//eeprom read address
pReg[I2C_CONCLR] = I2CONCLR_SIC;//clear SI bit to transmit address

while(pReg[I2C_STAT] != 0x28);//state word must be 0x18
pReg[I2C_DAT] = lowaddress;//eeprom read address
pReg[I2C_CONCLR] = I2CONCLR_SIC;//clear SI bit to transmit address

while(pReg[I2C_STAT] != 0x28);//state word must be 0x28
pReg[I2C_CONSET] = I2CONSET_STO;//stop dummy write
pReg[I2C_CONCLR] = I2CONCLR_SIC;//clear SI bit
pReg[I2C_CONSET] = I2CONSET_STA;//send another start condition

while(pReg[I2C_STAT] != 0x8);
pReg[I2C_DAT] = 0xA1;//send read order:1010000+1
pReg[I2C_CONCLR] = (I2CONCLR_SIC|I2CONCLR_STAC);//clear SI bit to transmit read order

while(pReg[I2C_STAT] != 0x40);//state word 0x40
pReg[I2C_CONCLR] = I2CONCLR_SIC;//clear SI bit,read eeprom
while(pReg[I2C_STAT] != 0x58);//received a data word,no ACK
data = (unsigned char)pReg[I2C_DAT];//read data


pReg[I2C_CONCLR] = (I2CONCLR_SIC|I2CONCLR_AAC);
pReg[I2C_CONSET] = I2CONSET_STO;//set STO bit to stop transmit
return data;
}
hjiongh 2009-03-20
  • 打赏
  • 举报
回复
当然现在不会是crc的问题,因为crc只是做校验而已,但是实际读出来的值是在内存里面的,我现在在debug,读出来后,我可以直接看到的呀

现在我试了一个连续多字节写来代替页写。 发生奇怪现象。

页写时,出错在267,268页, 而我byte写时,出错在268,269 页。
zyzhang365 2009-03-20
  • 打赏
  • 举报
回复
可以把你程序贴出来让大家帮你看看。
zyzhang365 2009-03-20
  • 打赏
  • 举报
回复
先不要这么肯定,可能是程序什么地方的问题,因为你单独写就没有问题。
hjiongh 2009-03-20
  • 打赏
  • 举报
回复
不是crc,我debug的时候直接看内存的,内存里面就不对。

现在我发现,这个错误有时候会变成268页,真是奇怪到底。
zyzhang365 2009-03-20
  • 打赏
  • 举报
回复
可能是CRC计算程序的问题。
hjiongh 2009-03-20
  • 打赏
  • 举报
回复
并且我换了其他片子,也是有同样的问题
hjiongh 2009-03-20
  • 打赏
  • 举报
回复
对的,是第267页的,我现在如果去掉267页,其他511页连写,再连读,crc校验是好的。
但是267页我单独页读写也是好的,放到一起去就不行了,真奇怪。

zyzhang365 2009-03-20
  • 打赏
  • 举报
回复
rx[266][]这应该是267页的东西了
hjiongh 2009-03-20
  • 打赏
  • 举报
回复
我用了二维数组,EEPROM_Tx_Buffer[512][64]; EEPROM_Rx_Buffer[512][64];
当我全部读出来后,我发现266页的

rx[266][36] 0x01
rx[266][37] 0x00
rx[266][38] 0x00
rx[266][39] 0x00

rx[266][48] 0x00
rx[266][49] 0xc0
rx[266][50] 0x05
rx[266][51] 0xe0

这是为什么? 我换了块eeprom, 这几个地址还是读出来这种数值,这是为什么?

zyzhang365 2009-03-20
  • 打赏
  • 举报
回复
你可以定位一下出错页的位置,首先保证写成功。你校验的思路是对的。
也可已每写一页然后接着读出来比较,这样可以定位什么地方失败了。

前面不能page mode写是怎么解决的?

21,604

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧