搜索
bottom↓
回复: 24

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

[复制链接]

出0入296汤圆

发表于 2008-6-18 02:23:27 | 显示全部楼层 |阅读模式
本帖最后由 Gorgon_Meducer 于 2012-8-7 13:59 编辑


  >>RD_EEPROM.h

  1. #ifndef _USE_EEPROM_H_
  2. #define _USE_EEPROM_H_
  3. /***********************************************************
  4. *   声明库说明:EEPROM存取操作底层函数声明库               *
  5. *   版本:      v1.00                                      *
  6. *   作者:      王卓然                                     *
  7. *   创建日期:  2008年4月18日                              *
  8. * -------------------------------------------------------- *
  9. *  [支 持 库]                                              *
  10. *   支持库名称:                                           *
  11. *   需要版本:                                             *
  12. *   支持库说明:                                           *
  13. * -------------------------------------------------------- *
  14. *  [版本更新]                                              *
  15. *   修改:                                                 *
  16. *   修改日期:                                             *
  17. *   版本:                                                 *
  18. * -------------------------------------------------------- *
  19. *  [版本历史]                                              *
  20. * -------------------------------------------------------- *
  21. *  [使用说明]                                              *
  22. ***********************************************************/

  23. /********************
  24. * 头 文 件 配 置 区 *
  25. ********************/

  26. /********************
  27. *   系 统 宏 定 义  *
  28. ********************/

  29. /*------------------*
  30. *   常 数 宏 定 义  *
  31. *------------------*/

  32. /*------------------*
  33. *   动 作 宏 定 义  *
  34. *------------------*/
  35. # define EEPROM_READ(__ADDR,__VAL)  \
  36.                 EEPROM_Read((__ADDR),&(__VAL),sizeof(__VAL))
  37. # define EEPROM_WRITE(__ADDR,__VAL)  \
  38.                 EEPROM_Write((__ADDR),&(__VAL),sizeof(__VAL))

  39. /********************
  40. *  用户变量类型定义 *
  41. ********************/

  42. /********************
  43. *    结构体定义区   *
  44. ********************/

  45. /********************
  46. *   函 数 引 用 区  *
  47. ********************/
  48. extern BOOL EEPROM_Write(UINT16 wAddress,void *pData,UINT16 wLength);
  49. extern BOOL EEPROM_Read(UINT16 wAddress,void *pData,UINT16 wLength);
  50. /********************
  51. *   全局变量引用区  *
  52. ********************/

  53. #endif
复制代码

出0入296汤圆

 楼主| 发表于 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;
}

出0入296汤圆

 楼主| 发表于 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);
……

出0入0汤圆

发表于 2008-6-23 14:54:52 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-6-26 14:36:40 | 显示全部楼层
顶!谢谢楼主分享,请问:SAFE_CODE_PERFORMANCE 是什么?什么编译器中的定义

出0入296汤圆

 楼主| 发表于 2008-6-26 17:01:55 | 显示全部楼层
to 【4楼】 xininye
    这是一个自定义的宏。用来实现原子操作,用来防止括号内的代码被中断处
理程序打断。具体定义在我的基础头文件中。

出0入0汤圆

发表于 2008-11-24 17:36:56 | 显示全部楼层
mark!

出0入0汤圆

发表于 2009-6-12 10:46:01 | 显示全部楼层
ddddddddddddddddd

出0入0汤圆

发表于 2009-6-16 10:09:52 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-7-9 11:31:32 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-7-16 16:16:26 | 显示全部楼层
Mark

出0入0汤圆

发表于 2009-7-30 22:16:09 | 显示全部楼层

出0入296汤圆

 楼主| 发表于 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>[目录结构]


    [Project]
       |
       - 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)

出0入0汤圆

发表于 2009-7-31 09:56:13 | 显示全部楼层
很好,参考了,也谢了

出0入0汤圆

发表于 2009-8-1 15:09:00 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2009-8-8 03:41:24 | 显示全部楼层
挖挖古墓

出0入0汤圆

发表于 2010-8-10 16:32:32 | 显示全部楼层
ddddddd

出0入0汤圆

发表于 2010-9-30 20:01:57 | 显示全部楼层
古董

出0入0汤圆

发表于 2011-10-16 19:32:50 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-8-7 13:41:17 | 显示全部楼层
mark!!!感谢楼主,正好能用上!

出0入0汤圆

发表于 2013-1-9 23:07:21 | 显示全部楼层
学习了,学习了

出0入0汤圆

发表于 2013-1-29 20:44:39 来自手机 | 显示全部楼层
这个用的上,谢谢

出0入0汤圆

发表于 2013-5-21 16:28:18 | 显示全部楼层
mark一下,在准备做掉电保护

出0入0汤圆

发表于 2013-7-31 14:13:29 | 显示全部楼层
学习         

出0入0汤圆

发表于 2013-8-12 09:23:29 | 显示全部楼层
马克 马上要用
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-1 11:46

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表