3942|11

67

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请教一个CRC校验的问题。 [复制链接]

我现在要测试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有某些页有特殊处理?

最新回复

测试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; iphysI2C;   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; }  详情 回复 发表于 2009-3-23 10:07
点赞 关注

回复
举报

73

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
你可以定位一下出错页的位置,首先保证写成功。你校验的思路是对的。
也可已每写一页然后接着读出来比较,这样可以定位什么地方失败了。

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

回复

74

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
我用了二维数组,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, 这几个地址还是读出来这种数值,这是为什么?

 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

4
 
rx[266][]这应该是267页的东西了   
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

5
 
对的,是第267页的,我现在如果去掉267页,其他511页连写,再连读,crc校验是好的。
但是267页我单独页读写也是好的,放到一起去就不行了,真奇怪。

 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

6
 
并且我换了其他片子,也是有同样的问题
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

7
 
可能是CRC计算程序的问题。
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

8
 
不是crc,我debug的时候直接看内存的,内存里面就不对。

现在我发现,这个错误有时候会变成268页,真是奇怪到底。
 
 
 

回复

87

帖子

0

TA的资源

一粒金砂(初级)

9
 
先不要这么肯定,可能是程序什么地方的问题,因为你单独写就没有问题。      
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

10
 
可以把你程序贴出来让大家帮你看看。
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

11
 
当然现在不会是crc的问题,因为crc只是做校验而已,但是实际读出来的值是在内存里面的,我现在在debug,读出来后,我可以直接看到的呀

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

页写时,出错在267,268页, 而我byte写时,出错在268,269 页。
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

12
 
测试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     {
        addr = (INT32U)(ADDR_PAGE_0 + (i*EEPROM_PAGE_SIZE));
        for (j=0; j         {
            EEPROM_Tx_Buffer[j] = (INT8U)(0x55);
        }

        crc_reg = CRC_CheckCRC16_CCITT(EEPROM_Tx_Buffer, EEPROM_PAGE_SIZE , crc_reg);

        PRO_EEPROM_WritePages(i2c_tMod, addr, EEPROM_Tx_Buffer, 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     {
        addr = (INT32U)(ADDR_PAGE_0 + (i*EEPROM_PAGE_SIZE));
        PRO_EEPROM_ReadBytes(i2c_tMod, addr, EEPROM_Rx_Buffer, EEPROM_PAGE_SIZE, &errcode);

        crc_reg = CRC_CheckCRC16_CCITT(EEPROM_Rx_Buffer, EEPROM_PAGE_SIZE , crc_reg);
          
                for(j=0; j                 {
                if(EEPROM_Rx_Buffer[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;
}
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表