AVR单片机EEPROM的操作

发布者:bettylove最新更新时间:2016-08-16 来源: eefocus关键字:AVR单片机  EEPROM 手机看文章 扫描二维码
随时随地手机看文章
本程序简单的示范了如何使用ATMEGA16的EERPOM

     EEPROM的简介
     EEPROM的写操作
     EEPROM的读操作

出于简化程序考虑,各种数据没有对外输出,学习时建议使用JTAG ICE硬件仿真器
 在打开调试文件到JTAG后,
 打开Debug -> JTAG ICE Options菜单,
 然后在JTAG ICE Properties中点击Dbug页面,将preserve eeprom选项选中。
 在每次仿真调试时候,就保护EEPROM内容了。
 否则,会按照默认设置擦除EEPROM的内容。 
 
 由于定义了EEPROM变量,JTAG调试时会询问是否初始化EEPROM,请选择[否]
 
 EEPROM的数据也可以在view->memory,选Eeprom窗口下察看
*/

#include
#include
////时钟定为内部1MHz,F_CPU=1000000  时钟频率对程序的运行没什么影响
/*
GCCAVR(avr-libc)里面自带了EEPROM的读写函数。
下面列举部分常用函数(原型)

#define eeprom_is_ready() bit_is_clear(EECR, EEWE)
检测EEPROM是否准备好。OK返回1(返回EEWE位)

#define eeprom_busy_wait() do {} while (!eeprom_is_ready())
等待EEPROM操作完成

extern uint8_t eeprom_read_byte (const uint8_t *addr);
读取指定地址的一个字节8bit的EEPROM数据

extern uint16_t eeprom_read_word (const uint16_t *addr);
读取指定地址的一个字16bit的EEPROM数据

extern void eeprom_read_block (void *buf, const void *addr, size_t n);
读取由指定地址开始的指定长度的EEPROM数据

extern void eeprom_write_byte (uint8_t *addr, uint8_t val);
向指定地址写入一个字节8bit的EEPROM数据

extern void eeprom_write_word (uint16_t *addr, uint16_t val);
向指定地址写入一个字16bit的EEPROM数据

extern void eeprom_write_block (const void *buf, void *addr, size_t n);
由指定地址开始写入指定长度的EEPROM数据

但不支持部分AVR,原文如下:
\note This library will \e not work with the following devices since these
    devices have the EEPROM IO ports at different locations:

    - AT90CAN128
    - ATmega48
    - ATmega88
    - ATmega165
    - ATmega168
    - ATmega169
    - ATmega325
    - ATmega3250
    - ATmega645
    - ATmega6450
*/

/*
在程序中对EEPROM 操作有两种方式
方式一:直接指定EERPOM 地址
    即读写函数的地址有自己指定,用于需要特定数据排列格式的应用中
方式二:先定义EEPROM 区变量法
 在这种方式下变量在EEPROM 存储器内的具体地址由编译器自动分配。
 相对方式一,数据在EEPROM 中的具体位置是不透明的。
 为EEPROM 变量赋的初始值,编译时被分配到.eeprom 段中,
 可用avr-objcopy 工具从.elf文件中提取并产生ihex 或binary 等格式的文件,
 从而可以使用编程器或下载线将其写入到器件的EEPROM 中。
 实际上WINAVR 中MFILE 生成的MAKEFILE 已经为我们做了这一切。
 它会自动生成以 “.eep” 为后缀的文件,通常它是iHex 格式
 (这次测试发现 分配地址是从0x0000开始的,故增加了一个EEPROM变量Evalvoid[16])
 
如果同时使用方式1和2,请注意防止地址重叠,自己指定的地址应该选在后面。
*/

//全局变量
unsigned char EDATA;

unsigned char ORGDATA[16]={0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,
         0x01,0x03,0x05,0x07,0x09,0x0B,0x0D,0x0F}; //原始数据

unsigned char CMPDATA[16];            //比较数据

//仿真时在watch窗口,监控这些全局变量。

//EEPROM 变量定义
unsigned char Evalvoid[16] __attribute__((section(".eeprom"))); //这个没用到
unsigned char Eval[16] __attribute__((section(".eeprom")));

int main(void)
{
 eeprom_write_byte (0x40,0xA5);  //向EEPROM的0x40地址写入数据 0xA5
 EDATA=eeprom_read_byte (0x40);  //读出,然后看看数据对不对?
 //上面两句编译是有如下警告,但不必理会
 //EEPROM_main.c:103: warning: passing arg 1 of `eeprom_write_byte' makes pointer from integer without a cast
 //EEPROM_main.c:104: warning: passing arg 1 of `eeprom_read_byte' makes pointer from integer without a cast
 
 eeprom_write_block (&ORGDATA[0], &Eval[0], 16);  //块写入
 //看看EEPROM数据是否是能失电永久保存,可以注释上面这句程序(不写入,只是读出),然后编译,烧写,断电(一段时间),上电,调试。
 eeprom_read_block (&CMPDATA[0],&Eval[0], 16);    //块读出,然后看看数据对不对?
 
    while (1);    
}

/*
ATmega16 包含512 字节的EEPROM 数据存储器。
它是作为一个独立的数据空间而存在的,可以按字节读写。
EEPROM的寿命至少为100,000 次擦除周期。
EEPROM的访问由地址寄存器EEAR、数据寄存器EEDR和控制寄存器EECR决定。
也可以通过ISP和JTAG及并行电缆来固化EEPROM数据

EEPROM数据的读取:
 当EEPROM地址设置好之后,需置位EERE以便将数据读入EEDR。
 EEPROM数据的读取需要一条指令,且无需等待。
 读取EEPROM后CPU 要停止4 个时钟周期才可以执行下一条指令。
注意:用户在读取EEPROM 时应该检测EEWE。如果一个写操作正在进行,就无法读取EEPROM,也无法改变寄存器EEAR。

EEPROM数据的写入:
1 EEPROM的写访问时间(自定时时间,编程时间)
    自定时功能可以让用户软件监测何时可以开始写下一字节。(可以采用中断方式)
 经过校准的1MHz片内振荡器用于EEPROM定时,不倚赖CKSEL熔丝位的设置。
 改变OSCCAL寄存器的值会影响内部RC振荡器的频率因而影响写EEPROM的时间。
 EEPROM自定时时间约为8.5 ms 即1MHz片内振荡器的8448个周期
注意:这个时间是硬件定时的,数值比较保险,其实真正的写入时间根本就用不了8.5mS那么长,而且跟电压有关,但芯片没有提供其他的检测编程完成的方法 
     这个问题表现在旧版的AT90S系列上面,由于没有自定时,数值定得太短,ATMEL给人投诉到头都爆,呵呵!
参考: 《用ATmega8535替换AT90S8535》文档里面的
     写EEPROM定时的改进
     在AT90S8535中写EEPROM的时间取决于供电电压,通常为2.5ms@VCC=5V4ms@VCC=2.7V
     ATmega8535中写EEPROM的时间为8448个校准过的RC振荡器周期 (与系统时钟的时钟源和频率无关)。
     假定校准过的RC振荡器为1.0MHz,则写时间的典型值为8.4ms,与VCC 无关。
     
2 为了防止无意识的EEPROM 写操作,需要执行一个特定的写时序
     (如果使用编译器的自带函数,无须自己操心)
 写时序如下( 第3 步和第4 步的次序并不重要):
 1. 等待EEWE 位变为零
 2. 等待SPMCSR 中的SPMEN 位变为零
 3. 将新的EEPROM 地址写入EEAR( 可选)
 4. 将新的EEPROM 数据写入EEDR( 可选)
 5. 对EECR 寄存器的EEMWE 写"1",同时清零EEWE
 6. 在置位EEMWE 的4 个周期内,置位EEWE
 经过写访问时间之后,EEWE 硬件清零。
 用户可以凭借这一位判断写时序是否已经完成。
 EEWE 置位后,CPU要停止两个时钟周期才会运行下一条指令。


注意:
 1:在CPU 写Flash 存储器的时候不能对EEPROM 进行编程。
   在启动EEPROM 写操作之前软件必须检查 Flash 写操作是否已经完成
      步骤(2) 仅在软件包含引导程序并允许CPU对Flash 进行编程时才有用。
      如果CPU 永远都不会写Flash,步骤(2) 可省略。
      
 2:如果在步骤5 和6 之间发生了中断,写操作将失败。
      因为此时EEPROM 写使能操作将超时。
      如果一个操作EEPROM的中断打断了另一个EEPROM操作,EEAR 或EEDR寄存器可能被修改,引起EEPROM 操作失败。
      建议此时关闭全局中断标志I。
      经过写访问时间之后,EEWE 硬件清零。用户可以凭借这一位判断写时序是否已经完成。
      EEWE 置位后,CPU要停止两个时钟周期才会运行下一条指令。
    

在掉电休眠模式下的EEPROM写操作
 若程序执行掉电指令时EEPROM 的写操作正在进行, EEPROM 的写操作将继续,并在指定的写访问时间之前完成。
 但写操作结束后,振荡器还将继续运行,单片机并非处于完全的掉电模式。因此在执行掉电指令之前应结束EEPROM 的写操作。
 
防止EEPROM数据丢失
 若电源电压过低,CPU和EEPROM有可能工作不正常,造成EEPROM数据的毁坏(丢失)。
   **这种情况在使用独立的EEPROM 器件时也会遇到。因而需要使用相同的保护方案。
 由于电压过低造成EEPROM 数据损坏有两种可能:
  一是电压低于EEPROM 写操作所需要的最低电压;
  二是CPU本身已经无法正常工作。
 EEPROM 数据损坏的问题可以通过以下方法解决:
  当电压过低时保持AVR RESET信号为低。
  这可以通过使能芯片的掉电检测电路BOD来实现。如果BOD电平无法满足要求则可以使用外部复位电路
  若写操作过程当中发生了复位,只要电压足够高,写操作仍将正常结束。
   (EEPROM在2V低压下也能进行写操作---有可以工作到1.8V的AVR芯片)
  
掉电检测BOD的误解
  AVR自带的BOD(Brown-out Detection)电路,作用是在电压过低(低于设定值)时产生复位信号,防止CPU意外动作.
  对EEPROM的保护作用是当电压过低时保持RESET信号为低,防止CPU意外动作,错误修改了EEPROM的内容
  
  而我们所理解的掉电检测功能是指 具有预测功能的可以进行软件处理的功能。
  例如,用户想在电源掉电时把SRAM数据转存到EEPROM,可行的方法是 
     外接一个在4.5V翻转的电压比较器(VCC=5.0V,BOD=2.7V),输出接到外部中断引脚(或其他中断)
     一但电压低于4.5V,马上触发中断,在中断服务程序中把数据写到EEPROM中保护起来
 注意: 写一个字节的EEPROM时间长达8mS,所以不能写入太多数据,电源滤波电容也要选大一些
关键字:AVR单片机  EEPROM 引用地址:AVR单片机EEPROM的操作

上一篇:AVR的IO端口特性与应用
下一篇:AVR_M8 BootLoader应用范例

推荐阅读最新更新时间:2024-03-16 15:05

AVR单片机的熔丝与解锁
AVR单片机的熔丝位配置是AVR单片机初学者很容易出错的地方,其实只要注意一些事项,还是能够尽量避免单片机被锁死,即使单片机被锁死,也可以使用一些方法解锁,本文讲述我在刚开始接触AVR单片机时熔丝位配置出现的一些问题。 1、AVR单片机的熔丝位是比较独到的特征,可以控制系统的时钟,JTAG调试、看门狗、芯片加密等等。图1是progisp软件,对于初学者来说,对熔丝位不熟悉,可以先将2处的编程熔丝对勾去掉,这样在编程的时候,就不会对熔丝位进行编程,单片机出厂的默认设置就可以使用。点击1处进入熔丝位配置界面。 图1 图2为位配置方式,这里的每一位都不能随意点击,尤其是熔丝低位控制时钟的地方,一般来说,直接对位进行配置并不
[单片机]
<font color='red'>AVR单片机</font>的熔丝与解锁
MC9S12XE的模拟EEPROM综述
Overview of the MC9S12XE Emulated EEPROM by: Martyn Gallop East Kilbride, Scotland 介绍 MC9S12XEP100是S12X微控制器家族中第一个用上低能耗0.18μ技术的。这个文档介绍了S12XE对于一个新的、具有高度灵活性和扩展性的模拟EEPROM(EEE)架构的支持。 由于FTM存储控制器提供的高度的整合,访问与更新EEE中的数据就好似使用一个NVRAM。在配置了它之后,应用程序就可以像访问普通RAM那样访问动态的NVM数据了,但这个数据可是下电不丢失的哦。 目标 这篇文档的目标是详述可以怎么使用存储控制器命令来配置和使用EEE。其中还综
[单片机]
MC9S12XE的模拟<font color='red'>EEPROM</font>综述
基于AVR单片机视觉智能寻迹车设计与实现方案
0 引 言 智能运输系统是未来交通运输系统发展的趋势,智能汽车在智能运输系统中扮演着十分重要的角色。作者提出智能寻迹车作为构建未来智能交通运输系统中重要部分,针对未来交通运输系统有导航线的环境命题假设下智能汽车的自主寻迹问题,提出一种基于视觉的智能寻迹车模设计方案,作为该假设问题的解决方案。 基于视觉的智能寻迹车模设计方案能够在线型复杂,转弯半径不确定性大的情况下,利用视觉自主寻迹前进,分级精确转向。 1 系统总体设计 基于视觉的智能寻迹车模系统以AVR单片机MEGAl6为核心,由单片机模块、路径识别模块、直流电机驱动模块、舵机驱动模块等组成,如图1所示。 直流电动机为车辆的驱动装置,转向电动机用于控制车辆行驶方
[单片机]
基于<font color='red'>AVR单片机</font>视觉智能寻迹车设计与实现方案
DSP 的IC 引导装载方法的研究与实现
  DSP 芯片的片上引导装载程序(Bootloader) 用于在系统上电时将用户程序从外部非易失性慢速存储器(如FLASH 等)或外部控制器(如ARM 等) 中装载到片内或者片外的高速存储器中高速运行 。DSP 芯片一般都提供多种引导装载模式,如Host 引导装载、EMIF 引导装载、I2C 引导装载、Serial RapidIO 引导装载等。相比其它几种模式而言,I2C 引导装载具有体积小、功耗低、连接简单等优点。本文以TI 公司的DSP 芯片TMS320C6455 (以下简称C6455)为例,详细介绍了I2C 引导装载模式的实现步骤,并构建了一个小系统验证引导装载的实现过程。   1 C6455 的引导装载模式介绍   
[嵌入式]
AVR单片机用哪个编译器好
我现在用AVR STUDIO+WINavr,刚开始还行,但慢慢发现当你在程序中想看一个函数或者变量的定义时,没办法跳转过去,只能自己找到相应的定义(至少我不知道怎么跳转),这个很不方便,我用AVR STUDIO+WINavr是因为能和protues一起单步调试仿真,但无法跳转很不舒服,另外我没有仿真器,其实连个AVR的片子都没有,别说买个,暂时没这打算,我买的有51的板子,ARM9的 板子,这几天需要了解AVR但不打算买什么硬件,在这种情况下,用哪个编译软件好要,最好能和protues一起仿真。 IAR效率最高,但收费。atmel studio是atmel自己的编译器,基于gcc,免费。 不二选择:AVR Studio 4.1
[单片机]
<font color='red'>AVR单片机</font>用哪个编译器好
AVR单片机比较匹配清零计数器模式的操作步骤及过程
当计数器TCNT0的数值等于比较寄存器OCR0时计数器TCNT0自动清零。OCR0定义了计数器的最大(TOP)值,这个模式使得用户可以很容易地控制比较匹配输出的频率。T/C0的比较输出脚为OC0(PB3),PB口的第三脚,在此模式下可以在OC0上输出PWM控制外部设备。 例如:在OC0脚上输出20HZ的方波信号,方波的周期时间为T=1/20HZ=0.05秒=50ms,半个周期为25ms,系统采用8MHZ晶振,1024分频,时钟计数频率为8000000/1024=7812.5HZ,每个时钟脉冲时间为1/7812.5=0.128ms, 定时25ms的计数值为25ms/0.128ms=195,将195赋值为T/C0的比较寄存器OCR
[单片机]
<font color='red'>AVR单片机</font>比较匹配清零计数器模式的操作步骤及过程
小小的水果竟能驱动AVR单片机
能工作的水果供电的AVR单片机的配置如下: 硬件:Mega88,32KHz外部晶振,2倍负压电路由AVR的PWM驱动,LCD是静态的笔端式LCD,用Mega88的IO口直接驱动,没有分时扫描。 软件:在Timer0中断服务程序中每2秒钟刷新LCD显示,平时AVR工作在空闲模式。Timer1提供PWM波形驱动2倍负压电路。 测量数据: 电路工作时水果电池电压2.5V,整机电流30uA,2倍负电压提供电压大约-3V。 本来觉得水果电池驱动LCD只是展示会上的噱头,三片柠檬的电力,应该足够带动LCD的。不过最初当我用Mega8L做了一个电路却不能用水果电池驱动时,我下决心亲自实践一番,看看水果供电的AVR单片机能否成功。这样
[单片机]
小小的水果竟能驱动<font color='red'>AVR单片机</font>?
AVR单片机I/O口读74HC165接口程序
AVR单片机I/O口读74HC165接口程序 /******************************** AVR单片机I/O口读74HC165接口程序 文件名:serin.c 编译:WinAVR-20070525 硬件:ATMEGA16 时钟:7372800 Hz 此程序在硬件上调试通过! 芯艺设计室 2004-2007 版权所有 转载请保留本注释在内的全部内容 WEB: http://www.chipart.cn Email: changfutong@sina.com ***************************
[单片机]
<font color='red'>AVR单片机</font>I/O口读74HC165接口程序
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved