Gorgon_Meducer 发表于 2008-6-18 02:23:27

[古董贴][共享]AVR通用EERPOM读写函数,兼容ICC原有的eeprom.h...

本帖最后由 Gorgon_Meducer 于 2012-8-7 13:59 编辑

>>RD_EEPROM.h
#ifndef _USE_EEPROM_H_
#define _USE_EEPROM_H_
/***********************************************************
*   声明库说明:EEPROM存取操作底层函数声明库               *
*   版本:      v1.00                                    *
*   作者:      王卓然                                     *
*   创建日期:2008年4月18日                              *
* -------------------------------------------------------- *
*[支 持 库]                                              *
*   支持库名称:                                           *
*   需要版本:                                             *
*   支持库说明:                                           *
* -------------------------------------------------------- *
*[版本更新]                                              *
*   修改:                                                 *
*   修改日期:                                             *
*   版本:                                                 *
* -------------------------------------------------------- *
*[版本历史]                                              *
* -------------------------------------------------------- *
*[使用说明]                                              *
***********************************************************/

/********************
* 头 文 件 配 置 区 *
********************/

/********************
*   系 统 宏 定 义*
********************/

/*------------------*
*   常 数 宏 定 义*
*------------------*/

/*------------------*
*   动 作 宏 定 义*
*------------------*/
# define EEPROM_READ(__ADDR,__VAL)\
                EEPROM_Read((__ADDR),&(__VAL),sizeof(__VAL))
# define EEPROM_WRITE(__ADDR,__VAL)\
                EEPROM_Write((__ADDR),&(__VAL),sizeof(__VAL))

/********************
*用户变量类型定义 *
********************/

/********************
*    结构体定义区   *
********************/

/********************
*   函 数 引 用 区*
********************/
extern BOOL EEPROM_Write(UINT16 wAddress,void *pData,UINT16 wLength);
extern BOOL EEPROM_Read(UINT16 wAddress,void *pData,UINT16 wLength);
/********************
*   全局变量引用区*
********************/

#endif

Gorgon_Meducer 发表于 2008-6-18 02:24:07

>>RD_EEPROM.c
/***********************************************************
*   函数库说明:EEPROM存取操作底层函数库                   *
*   版本:      v1.00                                    *
*   作者:      王卓然                                     *
*   创建日期:2008年4月18日                              *
* -------------------------------------------------------- *
*[支 持 库]                                              *
*   支持库名称:                                           *
*   需要版本:                                             *
*   支持库说明:                                           *
* -------------------------------------------------------- *
*[版本更新]                                              *
*   修改:                                                 *
*   修改日期:                                             *
*   版本:                                                 *
* -------------------------------------------------------- *
*[版本历史]                                              *
* -------------------------------------------------------- *
*[使用说明]                                              *
***********************************************************/

/********************
* 头 文 件 配 置 区 *
********************/
# include "RD_MacroAndConst.h"

/*如果你使用的是ICCV7.16以上版本,使用以下的语句*/
# include "iccioavr.h"

/*如果你使用的是ICC7.16以下版本,使用以下的语句*/
# include "iomXXv.h"   注意,这里的XX要替换成具体的单片机型号

/*如果你使用的不是ICC,则这里需要包含一个能提供CPU寄存器描述的头文件*/

/********************
*   系 统 宏 定 义*
********************/

/*------------------*
*   常 数 宏 定 义*
*------------------*/

/*------------------*
*   动 作 宏 定 义*
*------------------*/


/********************
*模块结构体定义区 *
********************/

/********************
*   函 数 声 明 区*
********************/
BOOL EEPROM_Write(UINT16 wAddress,void *pData,UINT16 wLength);
BOOL EEPROM_Read(UINT16 wAddress,void *pData,UINT16 wLength);

/********************
*   模块函数声明区*
********************/

/********************
*   模块变量声明区*
********************/

/********************
*   全局变量声明区*
********************/

/***********************************************************
*   函数说明:EEPROM写入函数                           *
*   输入:      要写入的地址,要写入的数据指针,数据长度   *
*   输出:      操作是否成功                               *
*   调用函数:无                                       *
***********************************************************/
BOOL EEPROM_Write(UINT16 wAddress,void *pData,UINT16 wLength)
{
    BYTE *pchData = pData;
   
    if (pData == NULL)
    {
      return FALSE;
    }
   
#if defined(__iom88v_h) || defined(__iom48v_h) || defined(__iom168v_h)
    /* M48/88/168的操作 */
    while(wLength--)
    {
      while(EECR & BIT(EEPE));
      while(SPMCSR & BIT(SELFPRGEN));
      EEAR = wAddress;
      if (EEAR != wAddress)
      {
            /* 无效的地址 */
            return FALSE;
      }
      EEDR = *pchData++;
      SAFE_CODE_PERFORMANCE
      (
            EECR |= BIT(EEMPE);
            EECR |= BIT(EEPE);
      )
      wAddress++;
    }
#else
    /* 普通AVR的操作 */
    while(wLength--)
    {
      while(EECR & BIT(EEWE));                            //等待上一次写数据完成
      while(SPMCR & BIT(SPMEN));                        //等待FLASH编程序
      EEAR = wAddress;
      if (EEAR != wAddress)
      {
            //无效的地址
            return FALSE;
      }
      EEDR = *pchData++;
      SAFE_CODE_PERFORMANCE
      (
            EECR |= BIT(EEMWE);
            EECR |= BIT(EEWE);
      )
      wAddress++;
    }
#endif
   
    return TRUE;
}

/***********************************************************
*   函数说明:EEPROM读取函数                           *
*   输入:      要读取的地址,要读取的数据指针,数据长度   *
*   输出:      操作是否成功                               *
*   调用函数:无                                       *
***********************************************************/
BOOL EEPROM_Read(UINT16 wAddress,void *pData,UINT16 wLength)
{
    BYTE *pchData = pData;
   
    if (pData == NULL)
    {
      return FALSE;
    }
#if defined(__iom88v_h) || defined(__iom48v_h) || defined(__iom168v_h)
    /* M48/88/168的操作 */
    while(wLength--)
    {
      while(EECR & BIT(EEPE));
      EEAR = wAddress;
      if (EEAR != wAddress)
      {
            //无效的地址
            return FALSE;
      }
      EECR |= BIT(EERE);
      NOP();
      *pchData++ = EEDR;
      wAddress++;
    }
#else
    /* 普通AVR的操作 */
    while(wLength--)
    {
      while(EECR & BIT(EEWE));                            //等待上一次写数据完成
      EEAR = wAddress;
      if (EEAR != wAddress)
      {
            //无效的地址
            return FALSE;
      }
      EECR |= BIT(EERE);
      NOP();
      *pchData++ = EEDR;
      wAddress++;
    }
#endif

    return TRUE;
}

Gorgon_Meducer 发表于 2008-6-18 02:32:27

>>使用方法
    1、如果你使用的是ICC,则根据自己的版本修改RD_EEPROM.c中一开始包含
       头文件的内容。
    2、如果你使用的是ICC7.16以上版本,在完成了以上步骤以后,就可以直接
       使用头文件了。如果你使用的是ICC7.16以下版本或者非ICC系统,则在
       使用M48/88/168时,需要在RD_EEPROM.c的一开始定义对应的宏:
       __iom48v_h、__iom88v_h 或者 __iom168v_h 。其他器件的情况,无需定
       义额外的宏。
    3、通过RD_EEPROM.h中的函数,可以写入或者读取连续字节的数据。注意不
       要读写地址为0的单元。
    4、烧写溶丝时,请开启BOD功能。
    5、该函数库修正了ICC自身EEPROM函数库的所有BUG。

>>应用举例:

#pragma data:eeprom
extern INT16 eep_nCounterZeroFixValue;
#pragma data:data
extern INT16 g_nCounterZeroFixValue;

……

/* 读取eep_nCounterZeroFixValue的值到g_nCounterZeroFixValue */
EEPROM_READ((int)&eep_nCounterZeroFixValue,g_nCounterZeroFixValue);

/* 将g_nCounterZeroFixValue的值写入到eep_nCounterZeroFixValue中 */
EEPROM_WRITE((int)&eep_nCounterZeroFixValue,g_nCounterZeroFixValue);
……

jszhouchao 发表于 2008-6-23 14:54:52

mark

xininye 发表于 2008-6-26 14:36:40

顶!谢谢楼主分享,请问:SAFE_CODE_PERFORMANCE 是什么?什么编译器中的定义

Gorgon_Meducer 发表于 2008-6-26 17:01:55

to 【4楼】 xininye
    这是一个自定义的宏。用来实现原子操作,用来防止括号内的代码被中断处
理程序打断。具体定义在我的基础头文件中。

guolinjie007 发表于 2008-11-24 17:36:56

mark!

0620221 发表于 2009-6-12 10:46:01

ddddddddddddddddd

bbi3014 发表于 2009-6-16 10:09:52

MARK

382383706 发表于 2009-7-9 11:31:32

MARK

jiaxueyong 发表于 2009-7-16 16:16:26

Mark

sleet1986 发表于 2009-7-30 22:16:09

Gorgon_Meducer 发表于 2009-7-30 23:20:46

最新版本:
[使用说明]
    A、此版本兼容ATmega系列的AVR单片机对EEPROM的读写
    B、兼容编译器为ICC、GCC和IAR
    C、对于GCC,请务必将优化选项设置为 -00以上,否则将无法使用该函数库
    D、库函数默认只开启EEPROM地读取部分,您可以通过将宏AVR_INTERNAL_EEPROM_READ定义为ES_DISABLED来
       关闭这部分功能;如果您想开启EEPROM的写入功能,您可以通过将宏AVR_INTERNAL_EEPROM_WRITE设置为
       ES_ENABLED来实现。所有这些宏设置应该在eeprom_cfg.h或者顶层的app_cfg.h中进行。
    E、通过ES_EEP_WRITE,可以将大型数据类型,比如结构体写入EEPROM,注意,这里的第二个参数不能为指针。
    F、通过ES_EEP_READ,可以从EEPROM中读取大型数据结构,同样,这里的第二个参数不能为指针。
    G、您可以直接通过函数EEPROM_Write()或者EEPROM_Read()来读写指定数量的数据。

<font color=red>[目录结构]
   
       |
       - HAL
          |
          - Driver
          ||
          |- EEPROM
          |      |
          |      - eeprom_cfg.h
          |      - eeprom.h
          |      - eeprom.c
          + UTILS

<font color=blue>eeprom.h
#ifndef _USE_EEPROM_H_
#define _USE_EEPROM_H_

/*-----------------------------*
*include head files         *
*----------------------------*/
#include "..\..\..\utils\compiler.h"
#include "eeprom_cfg.h"

/*-----------------------------*
*Macros for others          *
*----------------------------*/
#if AVR_INTERNAL_EEPROM_WRITE == ES_ENABLED
   # define ES_EEP_WRITE(__ADDR,__OBJECT)      \
            EEPROM_Write((uint16_t)(__ADDR),&(__OBJECT),sizeof((__OBJECT)))
#endif
#if AVR_INTERNAL_EEPROM_READ != ES_DISABLED
   # define ES_EEP_READ(__ADDR,__OBJECT)       \
            EEPROM_Read((uint16_t)(__ADDR),&(__OBJECT),sizeof((__OBJECT)))
#endif

/*-----------------------------*
*public functions prototypes*
*----------------------------*/
#if AVR_INTERNAL_EEPROM_WRITE == ES_ENABLED
extern ES_BOOL EEPROM_Write(uint16_t hwAddress,void *pData,uint16_t hwLength);
#endif
#if AVR_INTERNAL_EEPROM_READ != ES_DISABLED
extern ES_BOOL EEPROM_Read(uint16_t hwAddress,void *pData,uint16_t hwLength);
#endif

#endif

<font color=blue>eeprom.c
/*-----------------------------*
*include head files         *
*----------------------------*/
#include "..\..\..\utils\compiler.h"
#include "eeprom_cfg.h"


/*-----------------------------*
*Macros for constants       *
*----------------------------*/

/*-----------------------------*
*Macros for others          *
*----------------------------*/
<font color=blue>
#if __IS_COMPILER_IAR__
    #if !defined(EEPE)
      #define __IAR_SP_EEP_EXTEND_REG_NAME_SPACE__
    #endif
#endif
#if (!__IS_COMPILER_IAR__) || ((__IS_COMPILER_IAR__) && defined(__IAR_SP_EEP_EXTEND_REG_NAME_SPACE__))
#ifndef SPMCSR
   # define SPMCSR      SPMCR
#endif
#endif

#ifndef EEPE
   # define EEPE      EEWE
#endif
#ifndef EEMPE
   # define EEMPE       EEMWE      
#endif


/*-----------------------------*
*type definitions         *
*----------------------------*/

/*-----------------------------*
*structure,union and enum   *
*----------------------------*/

/*-----------------------------*
*public functions prototypes*
*----------------------------*/
#if AVR_INTERNAL_EEPROM_WRITE == ES_ENABLED
ES_BOOL EEPROM_Write(uint16_t hwAddress,uint8_t *pchData,uint16_t hwLength);
#endif
#if AVR_INTERNAL_EEPROM_READ != ES_DISABLED
ES_BOOL EEPROM_Read(uint16_t hwAddress,uint8_t *pchData,uint16_t hwLength);
#endif
/*-----------------------------*
*static functions prototypes*
*----------------------------*/


/*-----------------------------*
*public variable declaration*
*----------------------------*/

/*-----------------------------*
*static variable declaration*
*----------------------------*/

#if AVR_INTERNAL_EEPROM_WRITE == ES_ENABLED
/*-----------------------------------------------------------------------------*
*Function Description:                                                      *
*      Write data to eeprom.                                                *
*Parameters:                                                                *
*      hwAddress       put data to this address in eeprom. Caution, do not    *
*                      try to write datas from zero address.                  *
*      pchData         A pointer point to data buffer                         *
*      hwLength      data buffer size in byte.                              *
*Return                                                                     *
*      the result of proccessing (ES_TRUE / ES_FALSE)                         *
*----------------------------------------------------------------------------*/
ES_BOOL EEPROM_Write(uint16_t hwAddress,uint8_t *pchData,uint16_t hwLength)
{
    //! check the write buffer length
    if (hwLength == 0)
    {
      //! nothing to write...
      return ES_TRUE;
    }
   
    //! check the pointer...
    if (pchData == NULL)
    {
      //! the data buffer pointer is null
      return ES_FALSE;
    }
      
    if (hwAddress == 0)
    {
      //! could not write zero address...
      return ES_FALSE;
    }
   
    while(EECR & BIT(EEPE))
    {
      RELOAD_WATCHDOG
    }
    while(SPMCSR & BIT(SPMEN))
    {
      RELOAD_WATCHDOG
    }
   
    EEAR = (hwAddress + hwLength - 1);
    if (EEAR != (hwAddress + hwLength - 1))
    {
      //! Out of eeprom address space
      return ES_FALSE;
    }
      
    do
    {
      //! wait for eeprom ready
      while(EECR & BIT(EEPE))
      {
            RELOAD_WATCHDOG
      }
      while(SPMCSR & BIT(SPMEN))
      {
            RELOAD_WATCHDOG
      }
      
      //! load data address
      EEAR = hwAddress;
      EEDR = *pchData++;
      RELOAD_WATCHDOG
      
      //! eeprom writing sequence...
      SAFE_CODE_PERFORMANCE
      (
            EECR |= BIT(EEMPE);
            EECR |= BIT(EEPE);
      )
      hwAddress++;
    }
    while (--hwLength);
   
    return ES_TRUE;
}
#endif


#if AVR_INTERNAL_EEPROM_READ != ES_DISABLED
/*-----------------------------------------------------------------------------*
*Function Description:                                                      *
*      Read data from eeprom.                                                 *
*Parameters:                                                                *
*      hwAddress       put datas to this address in eeprom. Caution, do not   *
*                      try to write datas from zero address.                  *
*      pchData         A pointer point to data buffer                         *
*      hwLength      data buffer size in byte.                              *
*Return                                                                     *
*      the result of proccessing (ES_TRUE / ES_FALSE)                         *
*----------------------------------------------------------------------------*/
ES_BOOL EEPROM_Read(uint16_t hwAddress,uint8_t *pchData,uint16_t hwLength)
{
    //! check the read buffer length...
    if (hwLength == 0)
    {
      //! nothing to read.
      return ES_TRUE;
    }
   
    while(EECR & BIT(EEPE))
    {
      RELOAD_WATCHDOG
    }
    //! check the read buffer address
    if (pchData == NULL)
    {
      //! the pointer is a null value...
      return ES_FALSE;
    }
    EEAR = (hwAddress + hwLength - 1);
    if (EEAR != (hwAddress + hwLength - 1))
    {
      //! Out of eeprom address space
      return ES_FALSE;
    }
   
    do
    {
      //! wait for eeprom ready
      while(EECR & BIT(EEPE))
      {
            RELOAD_WATCHDOG
      }
      EEAR = hwAddress;
      RELOAD_WATCHDOG
      EECR |= BIT(EERE);
      NOP
      *pchData++ = EEDR;
      hwAddress++;
    }
    while (--hwLength);
   
    return ES_TRUE;
}

#endif

[相关下载]
点击此处下载 ourdev_465997.rar(文件大小:14K) <font color=green>(原文件名:EEPROM.rar)

maskiss 发表于 2009-7-31 09:56:13

很好,参考了,也谢了

sleet1986 发表于 2009-8-1 15:09:00

学习学习

xukaiming 发表于 2009-8-8 03:41:24

挖挖古墓

ywf85 发表于 2010-8-10 16:32:32

ddddddd

xtaens 发表于 2010-9-30 20:01:57

古董

tdncool12 发表于 2011-10-16 19:32:50

mark

kcity2008 发表于 2012-8-7 13:41:17

mark!!!感谢楼主,正好能用上!

bbxyliyang08 发表于 2013-1-9 23:07:21

学习了,学习了

jz701209李 发表于 2013-1-29 20:44:39

这个用的上,谢谢

xieguangye2001 发表于 2013-5-21 16:28:18

mark一下,在准备做掉电保护

lu976046395 发表于 2013-7-31 14:13:29

学习         

xieguangye 发表于 2013-8-12 09:23:29

马克 马上要用
页: [1]
查看完整版本: [古董贴][共享]AVR通用EERPOM读写函数,兼容ICC原有的eeprom.h...