您的位置 首页 电源

AVR单片机EEPROM的操作

本程序简单的示范了如何使用ATMEGA16的EERPOMEEPROM的简介EEPROM的写操作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 <avr/io.h>
#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 charEDATA;

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=5V,4ms@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,所以不能写入太多数据,电源滤波电容也要选大一些

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/dianyuan/273198.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部