打印

请问eeprom和铁电的驱动有什么区别,除了慢些.

[复制链接]
7599|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
alphal|  楼主 | 2008-1-26 18:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
huntington| | 2008-1-26 21:52 | 只看该作者

没理解LZ的意思~


既然和写入的不一样,为什么又是没有出现错误~~~~~
----------------------------------------------------------------------
我的iic的程序,在铁电上面测试读写10万多次没有问题,可是在eeprom上测试的时候,出现写入的数据读出会不一样,但并没有出现错误.
我的延时都是7个nop,一般也就4-5个就可以了吧.

为何这么大差别? 

使用特权

评论回复
板凳
hotpower| | 2008-1-27 12:25 | 只看该作者

一个nop都不用加,估计是程序问题~~~

使用特权

评论回复
地板
gyt| | 2008-1-27 13:24 | 只看该作者

hot大侠说的是

使用特权

评论回复
5
alphal|  楼主 | 2008-1-27 18:10 | 只看该作者

.........

to:huntington
出现写入的数据读出会不一样,但并没有出现错误.

没有错误是指器件的应答正常.

另外程序读写字节里面需要关中断吗?我发现似乎关不关都一样.

我帖上程序看看...

#define     AT24C256_I2cWRITE         0xA0    // 定义24CXX的器件地址SLA和方向位W 
#define     AT24C256_I2cREAD          0xA1    //定义24CXX的器件地址SLA和方向位R

#define      I2CEPR_DELAY                          _nop_();_nop_(); _nop_(); _nop_();     _nop_();     _nop_(); _nop_();

#define      SET_SDAEPR_HIGH                 epr_SDA = 1//    io_T_SDA = 1 /* set SDA to high */
#define      SET_SDAEPR_LOW                    epr_SDA = 0//io_T_SDA = 0 /* set SDA to low */

#define      SET_SCLEPR_HIGH                 epr_SCL = 1//io_T_SCL = 1 /* set SCL to high */
#define      SET_SCLEPR_LOW                    epr_SCL = 0//io_T_SCL = 0 /* set SCL to low */

#define     SET_SDAEPR_TO_INPUT              epr_SDA = 1//io_T_SDA = 1
#define     SET_SDAEPR_TO_OUTPUT       

#define     GET_SDAEPR_VALUE                 epr_SDA;//io_T_SDA

static void     _hwi2c_I2cSendStart(void);
static void     _hwi2c_I2cSendStop(void);
static void     _hwi2c_I2cSendNAck(void);
static u1_t     _u1_hwi2c_I2cGetAck(void);
static u1_t     _u1_hwi2c_I2cSendByte(u1_t value);
static void     _hwi2c_I2cSendAck(void);
static u1_t     _u1_hwi2c_I2cGetByte(void);
static u1_t     _u1_hwi2c_I2cGetLastByte(void);


/*
-----------------------------------------------------------------------------
Function name : _hwrtc_I2cSendStart  
Purpose :i2c bus write/read start program
Input parameters :none  
Output parameters : none
-----------------------------------------------------------------------------
*/
static void _hwi2c_I2cSendStart(void)
{
    SET_SDAEPR_HIGH;            //发送起始条件的数据信号     
    SET_SCLEPR_HIGH;                                     /* set SDA,SCL to high */
    I2CEPR_DELAY;                    //起始条件建立时间大于4.7us延时
    SET_SDAEPR_LOW;                //发送起始信号                      /* set SDA to low */
    I2CEPR_DELAY;                    //起始条件锁定时间大于4us
    SET_SCLEPR_LOW;                //钳住总线,准备发送或接收数据  /* set SCL to low */
    I2CEPR_DELAY;
}

/*
-----------------------------------------------------------------------------
Function name : _hwrtc_I2cSendStop  
Purpose :i2c bus write/read stop program
Input parameters :none  
Output parameters : none
-----------------------------------------------------------------------------
*/
static void _hwi2c_I2cSendStop(void)
{
    SET_SDAEPR_LOW;                                      /* set SDA to low */
    I2CEPR_DELAY ;
    SET_SCLEPR_HIGH;                                     /* set SCL to high */
    I2CEPR_DELAY ;
    SET_SDAEPR_HIGH;                                     /* set SDA to high */
    I2CEPR_DELAY ;
    SET_SCLEPR_LOW;  
}

/*
-----------------------------------------------------------------------------
Function name : _hwrtc_I2cSendNAck  
Purpose :Send NACK Signal
Input parameters :none  
Output parameters : none
-----------------------------------------------------------------------------
*/
static void _hwi2c_I2cSendNAck(void)
{
    SET_SDAEPR_HIGH;                         /* set SDA to high */
    I2CEPR_DELAY ;

    SET_SCLEPR_HIGH;                                     /* set SCL to high */
    I2CEPR_DELAY ;

    SET_SCLEPR_LOW;                                      /* set SCL to low */
    I2CEPR_DELAY ;
}


/*
-----------------------------------------------------------------------------
Function name : _u1_hwrtc_I2cGetAck  
Purpose :Get ACK Signal
Input parameters :none  
Output parameters : ACK Signal
-----------------------------------------------------------------------------
*/
static u1_t _u1_hwi2c_I2cGetAck(void)
{
    u1_t __temp = TRUE, __i = 0xFF;
//    bool_t __b_ea ;

//    __b_ea = _testbit_(EA) ;

    SET_SDAEPR_HIGH;                                             /* set SDA to high,Release SDA for ACK */
    I2CEPR_DELAY ;

    SET_SCLEPR_HIGH;                                             /* set SCL to high,raise ACK clock */

    while((--__i) && (__temp))
        {
             __temp = GET_SDAEPR_VALUE;
        } 

    SET_SCLEPR_LOW;                                              /* set SCL to low */

    I2CEPR_DELAY ;

//    EA = __b_ea ;

    if (__temp)                                              /* if success return 0x01,else return 0x00 */
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

/*
-----------------------------------------------------------------------------
Function name : _u1_hwrtc_I2cSendByte  
Purpose :Send one byte to I2C interface
Input parameters :value-the Byte that will be sent  
Output parameters : TRUE or FALSE
-----------------------------------------------------------------------------
*/
static u1_t _u1_hwi2c_I2cSendByte(u1_t value)
{
    u1_t         __i, __temp;
//    bool_t    __b_ea ;

//    __b_ea = _testbit_(EA) ;

    for (__i = 0; __i < BITSOFBYTE; __i++)
    {
        __temp = value;
        __temp >>= 7 - __i;
        __temp &= 0x01;

        if (__temp == 0)
        {
            SET_SDAEPR_LOW;
        }                              /* set SDA to low */
        else
        {
            SET_SDAEPR_HIGH;
        }                             /* set SDA to high */

        I2CEPR_DELAY ;

        SET_SCLEPR_HIGH;                                 /* set SCL to high */
        I2CEPR_DELAY ;
        SET_SCLEPR_LOW;                                  /* set SCL to low */
        I2CEPR_DELAY ;
    }

//    EA = __b_ea ;
    return(_u1_hwi2c_I2cGetAck());                         /* if sucess return 0x01,else return 0x00 */

}

/*
-----------------------------------------------------------------------------
Function name : _hwrtc_I2cSendAck  
Purpose :Send ACK Signal
Input parameters :none
Output parameters : none
-----------------------------------------------------------------------------
*/
static void _hwi2c_I2cSendAck(void)
{
    SET_SDAEPR_LOW;
    I2CEPR_DELAY ;
    SET_SCLEPR_HIGH;
    I2CEPR_DELAY ;

    SET_SCLEPR_LOW;
    I2CEPR_DELAY ;
}


/*
-----------------------------------------------------------------------------
Function name : _u1_hwrtc_I2cGetByte  
Purpose :Get one byte from  I2C interface
Input parameters :none
Output parameters : the byte from I2C interface
-----------------------------------------------------------------------------
*/
static u1_t _u1_hwi2c_I2cGetByte(void)
{
    u1_t         __i, __temp, __temp1;
//    bool_t    __b_ea ;

//    __b_ea = _testbit_(EA) ;

    __temp = 0;

    SET_SDAEPR_TO_INPUT;                

    for (__i = 0; __i < BITSOFBYTE; __i++)
    {
        __temp <<= 1;

        SET_SCLEPR_HIGH;
        I2CEPR_DELAY ;

        __temp1 = GET_SDAEPR_VALUE;
        __temp |= __temp1;

        SET_SCLEPR_LOW;
        I2CEPR_DELAY ;
    }

    SET_SDAEPR_TO_OUTPUT;

    _hwi2c_I2cSendAck();    
    
//    EA = __b_ea ;                
    return(__temp);
}


/*
-----------------------------------------------------------------------------
Function name : _u1_hwrtc_I2cGetLastByte  
Purpose :Get the last byte form I2C interface
Input parameters :none
Output parameters : the last byte from I2C interface
-----------------------------------------------------------------------------
*/
static u1_t _u1_hwi2c_I2cGetLastByte(void)
{
    u1_t         __i, __temp, __temp1;
//    bool_t    __b_ea ;

//    __b_ea = _testbit_(EA) ;

    __temp = 0;

    SET_SDAEPR_TO_INPUT;                         

    for (__i = 0; __i < BITSOFBYTE; __i++)
    {
        __temp <<= 1;

        SET_SCLEPR_HIGH;
        I2CEPR_DELAY ;
        __temp1 = GET_SDAEPR_VALUE;
        __temp |= __temp1;

        SET_SCLEPR_LOW;
        I2CEPR_DELAY ;
    }

//    SET_SDAEPR_TO_OUTPUT;                 edit by whs  no define

    _hwi2c_I2cSendNAck();

//    EA = __b_ea ;

    return(__temp);
}

/*=====================================================================================
函数: u1_hwi2cepr_I2ceprReadBlock
功能: eeprom连续写操作
参数: address:读数据的地址;pdat:读出数据存储地址;size:写入长度
返回: true:成功;false:失败
备注:
创建: whs-07-11-23
修改:
========================================================================================*/
u1_t u1_hwi2cepr_I2ceprReadBlock(u2_t address, u1_t* pdat, u1_t size) 
{  
    u1_t         __i;
  u1_t         __status;

    _hwi2c_I2cSendStart();
    __status = _u1_hwi2c_I2cSendByte(AT24C256_I2cWRITE);

  if (__status == TRUE)
  {
    __status = _u1_hwi2c_I2cSendByte((u1_t)(address>>BITSOFBYTE));   /*send the high byte first*/ 
  }

  if (__status == TRUE)
  {
    __status = _u1_hwi2c_I2cSendByte((u1_t)address);    
  }

  if (__status == TRUE)
  {
    _hwi2c_I2cSendStart();
    __status = _u1_hwi2c_I2cSendByte(AT24C256_I2cREAD);    
  }

  if (__status == TRUE)
  {
    for (__i=0; __i<size-1; __i++)
    {
      pdat[__i] = _u1_hwi2c_I2cGetByte();
    }
    pdat[__i] = _u1_hwi2c_I2cGetLastByte();
  }

    _hwi2c_I2cSendStop();


  return (__status);
}

/*=====================================================================================
函数: u1_hwi2cepr_I2ceprWriteBlock
功能: eeprom连续写操作
参数: address:写入地址;pdat:写入的数据;size:写入长度
返回: true:成功;false:失败
备注:
创建: whs-07-11-23
修改:
========================================================================================*/
u1_t u1_hwi2cepr_I2ceprWriteBlock(u2_t address, u1_t* pdat, u1_t size)
{
    u1_t     __i;
  u1_t     __status;
//    bool_t    b_ea ;

//    b_ea = _testbit_(EA) ;

    _hwi2c_I2cSendStart();
    __status = _u1_hwi2c_I2cSendByte(AT24C256_I2cWRITE);

  if (__status == TRUE)
  {
    __status = _u1_hwi2c_I2cSendByte((u1_t)(address>>BITSOFBYTE));   /*send the high byte first*/ 
  }

  if (__status == TRUE)
  {
    __status = _u1_hwi2c_I2cSendByte((u1_t)address);    
  }

  if (__status == TRUE)
  {
    for (__i=0; __i<size; __i++)
    {
      __status = _u1_hwi2c_I2cSendByte( *(pdat+__i) );
      if (__status == FALSE)
      {
        break;
      }
    }
  }

    _hwi2c_I2cSendStop();
  
//  EA = b_ea;  

  return (__status);
}


/*=====================================================================================
函数: hwi2cepr_I2ceprInit
功能: 初始化
参数: 
返回: 
备注:
创建: whs-07-11-23
修改:
========================================================================================*/
void hwi2cepr_I2ceprInit(void)
{
        u1_t __i ;

        SET_SDAEPR_HIGH ;

        for(__i = 0; __i < 9; __i++)
        {
         SET_SCLEPR_HIGH ;
         I2CEPR_DELAY;
         SET_SCLEPR_LOW ;
         I2CEPR_DELAY;
        }

    _hwi2c_I2cSendStop();
}

使用特权

评论回复
6
JOHN_light| | 2008-1-27 20:46 | 只看该作者

铁电无需延时,而EEPROM的写入需要延时为毫秒级

几个nop是不行嘀嘀嘀……

我嘀较早时发言:
“对于串行EEPROM的写操作,建议采用ACKNOWLEDGE POLLING代替延时ACKNOWLEDGE POLLING: Once the internally-timed write cycle has started and the EEPROM inputs are disabled, acknowledge polling CAN be initiated. This involves sending a start condition followed by the device address word. The Read/Write bit is representative of the operation desired. Only if the internal write cycle has completed will the EEPROM respond with a “0”, allowing the read or write sequence to continue.
简单地说就是在串行EEPROM开始内部写操作过程到完成这段时间,不管你试图进行读或者写操作,芯片都不会响应。

这样一来你就可以不断地尝试向该器件发出start condition,当它以“0”来应答时,则表明它的上一个写过程已经完成,你可以接着进行下一步的操作了。”

使用特权

评论回复
7
alphal|  楼主 | 2008-1-27 21:06 | 只看该作者

to 楼上

不断地尝试向该器件发出start condition,当它以“0”来应答时,则表明它的上一个写过程已经完成,你可以接着进行下一步的操作了

??
不是这儿吗?
SET_SDAEPR_HIGH;                                             /* set SDA to high,Release SDA for ACK */
    I2CEPR_DELAY ;

    SET_SCLEPR_HIGH;                                             /* set SCL to high,raise ACK clock */

    while((--__i) && (__temp))
        {
             __temp = GET_SDAEPR_VALUE;
        } 

    SET_SCLEPR_LOW;                                              /* set SCL to low */

使用特权

评论回复
8
alphal|  楼主 | 2008-1-27 21:09 | 只看该作者

毫秒级是指什么?

是nop的延时时间需要到毫秒级还是等待iic ask的时间毫秒级?

使用特权

评论回复
9
JOHN_light| | 2008-1-27 21:49 | 只看该作者

抱歉我有一个坏习惯是不喜欢看代码

ATMEL在AT24C512中写明Write Cycle Time最长可能达到
20m(1.8V)/10ms(2.7V)/10ms(5.0V)
当然这是最坏的情况。

使用特权

评论回复
10
xwj| | 2008-1-27 22:10 | 只看该作者

就是写了之后那么长时间内EEPROM是没反映的

下一个操作必须得等10mS后在给,不然eeprom肯定不甩你

使用特权

评论回复
11
alphal|  楼主 | 2008-1-28 11:48 | 只看该作者

是不是每次操作后的时间

每次操作(一次读或者写,不管是写一个字节还是连写多字节,都只是一次操作)后,最坏情况是10ms内都不能就行下一次操作.

是这样吧?

但是我的程序里操作一次后等待的时间是大于10ms的,等了40ms,可是还是有问题.
但相同的程序读写铁电就没有问题,铁电和eeprom是不是只是读写时间上的区别?

使用特权

评论回复
12
alphal|  楼主 | 2008-1-28 13:47 | 只看该作者

.............

我是地址依次从0增至100,连续写入50byte数据.芯片是24C256

好像和eepro内部翻页有关????
一次连续读/写操作中,地址不能跨页吗?????

使用特权

评论回复
13
alphal|  楼主 | 2008-1-28 15:00 | 只看该作者

好像是跨页的问题

我现在每次操作都是64byte,所以一次操作内就没有跨页,好像就正常了,跑了几千次还没发现问题.
据说是eeprom的写操作不能跨页?

不过现在,这个程序操作铁电反而会出错了,也是读出和写入的不一样,真是晕了....

使用特权

评论回复
14
xwj| | 2008-1-28 15:45 | 只看该作者

唉,自己去仔细读DataSheet

使用特权

评论回复
15
john_light| | 2008-1-28 16:41 | 只看该作者

EEPROM在连续写入超过一个页地址时会翻转回页首

同一页内之前写的数据就被覆盖了,仔细研读数据手册吧。

使用特权

评论回复
16
alphal|  楼主 | 2008-1-28 16:54 | 只看该作者

呵呵

呵呵,不好意思,没读datasheet....


谢谢各位大侠的指点..

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

112

主题

473

帖子

1

粉丝