博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AVR(Mega32)读写内部EEPROM
阅读量:4029 次
发布时间:2019-05-24

本文共 3650 字,大约阅读时间需要 12 分钟。

开发工具:codeblocks+winAVR2010

方式一:(根据Atmega32资料)其实就两个函数——不知道为什么有时候成功又时候失败(不明所以);结合这两个读写函数,可以自己重写出其他读写一个block的函数

unsigned char EEPROM_read(unsigned int uiAddress){/* Wait for completion of previous write */while(EECR & (1<
void EEPROM_write(unsigned int uiAddress, unsigned char ucData){/* Wait for completion of previous write */while(EECR & (1<

方式二:#include <avr/eeprom.h>借用其中定义好的函数

转自:http://blog.lixin.me/archives/29200/

在我使用的atmega16L的芯片中,包含 512 字节的 EEPROM 数据存储器。它是作为一个独立的数据空间而存在的。存储在EEPROM中的数据,在没有电的情况下下仍然可以保存,通俗的说类似电脑的硬盘。

EEPROM的访问需要涉及3个寄存器:地址寄存器、数据寄存器和控制寄存器。通过操作这3个寄存器来实现对EEPROM的操作。不过,在winavr中,已经提供了一个eeprom的操作类库给我们了,地址如下:

#include <avr/eeprom.h>

       该文件提供了几个函数,可以很方便地帮助我们完成对eeprom的操作。

eeprom_is_ready()

        这个函数返回一个布尔值,如果eeprom准备就绪的话会返回true。在对eeprom进行读写操作之前都应该先判断是否已经准备就绪。于是while(!eeprom_is_ready()){}这句话会出现在每个操作之前。

eeprom_busy_wait()

        这个函数其实是对上面eeprom_is_ready()的包装。正如上所说,每次都要先写一个while的等待不是个好方法,所以winavr就给包装一下。该函数的定义为:#define eeprom_busy_wait() do {} while (!eeprom_is_ready())

eeprom_write_byte(address,value)

        这个函数是向address这个eeprom地址写入一个字节。

eeprom_read_byte(address)

       这个函数是从address这个地址读取一个字节的内容。

其他函数如下:

Functions

• uint8_t eeprom_read_byte (const uint8_t __p) __ATTR_PURE__
• uint16_t eeprom_read_word (const uint16_t __p) __ATTR_PURE__
• uint32_t eeprom_read_dword (const uint32_t __p) __ATTR_PURE__
• float eeprom_read_float (const float __p) __ATTR_PURE__
• void eeprom_read_block (void __dst, const void __src, size_t __n)
• void eeprom_write_byte (uint8_t __p, uint8_t __value)
• void eeprom_write_word (uint16_t __p, uint16_t __value)
• void eeprom_write_dword (uint32_t __p, uint32_t __value)
• void eeprom_write_float (float __p, float __value)
• void eeprom_write_block (const void __src, void __dst, size_t __n)
• void eeprom_update_byte (uint8_t __p, uint8_t __value)
• void eeprom_update_word (uint16_t __p, uint16_t __value)
• void eeprom_update_dword (uint32_t __p, uint32_t __value)
• void eeprom_update_float (float __p, float __value)
• void eeprom_update_block (const void __src, void __dst, size_t __n)

接下来,来写一个简单的例子:

#include <avr/io.h>

#include <avr/eeprom.h>  //引入eeprom
#include <avr/interrupt.h> //中断使用

//外部中断0

ISR(INT0_vect){

eeprom_busy_wait();
eeprom_write_byte(1,0xf0); //向地址0x01写入数据0xf0
}

//外部中断1

ISR(INT1_vect){
eeprom_busy_wait();
PORTB=eeprom_read_byte(1); //从地址1读取数据并赋予PORTB
}
int main(void){
    cli();
    DDRB=0xff; //流水灯用的,设置为输出
    PORTB=0xff;  //输出高电平,led全灭
    DDRD=0xf3;//把两个中断用的端口设置为输入
    PORTD=0xff;
    GICR=0xc0;//中断0和中断1置位。
    MCUCR&=0xf0;//当低电平时触发中断
    sei();//开启全局中断使能。
    while(1);
}

上面的代码,我使用了PORTB作为led指示灯.并设置两个中断,低电位时触发。

实验方法是:

  1. 烧写程序入开发板。
  2. 按下按钮1,触发外部中断0,执行把0xf0数据写入eeprom中。
  3. 拔下电源,重新接通电源。
  4. 按下按钮2,触发外部中断1,执行从eeprom中读取数据,并通过led灯反馈结果。

不过在测试方式二的过程中,遇到一个小问题:http://blog.chinaunix.net/uid-11009175-id-4633984.html

今天在用codeblock打开几年前的avr工程,编译的时候,出错了,错误是 undefined reference to `__eewr_byte_m169p。
经过1个小时的努力,终于找到问题所在了。
解释:
As you see the EEPROM support has changed in recent years so that now the header files identify the AVR you are using (mega644) and then concatenate this onto the __eewr_byte_* style routine names and these are then provided in the link from the device specific .o file. When this works the map file shows something like:
e:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5\libc.a(eewr_byte_atmega644.o)
                              test.o (__eewr_byte_m644)
That's built on Windows with WinAVR but the point is that it's ../avr/lib/avr5/libc.a that is providing the function. If you get undefined ref then that suggests that you environment is not linking with the right libc.a
Maybe show your complete build output? Is the -mmcu=atmega644 being passed to the link as well as the compiles?

解决办法很简单,libc.a需要选择../avr/lib/avr5/libc.a这个才行。

你可能感兴趣的文章
CocoaPods实践之制作篇
查看>>
[Mac]Mac 操作系统 常见技巧
查看>>
苹果Swift编程语言入门教程【中文版】
查看>>
捕鱼忍者(ninja fishing)之游戏指南+游戏攻略+游戏体验
查看>>
iphone开发基础之objective-c学习
查看>>
iphone开发之SDK研究(待续)
查看>>
计算机网络复习要点
查看>>
Variable property attributes or Modifiers in iOS
查看>>
NSNotificationCenter 用法总结
查看>>
C primer plus 基础总结(一)
查看>>
剑指offer算法题分析与整理(一)
查看>>
剑指offer算法题分析与整理(三)
查看>>
部分笔试算法题整理
查看>>
Ubuntu 13.10使用fcitx输入法
查看>>
pidgin-lwqq 安装
查看>>
mint/ubuntu安装搜狗输入法
查看>>
C++动态申请数组和参数传递问题
查看>>
opencv学习——在MFC中读取和显示图像
查看>>
retext出现Could not parse file contents, check if you have the necessary module installed解决方案
查看>>
pyQt不同窗体间的值传递(一)——对话框关闭时返回值给主窗口
查看>>