AVR开发 Arduino方法(六) 内存子系统

  Arduino UNO R3主处理器ATMega328P的芯片内部拥有3种存储器:数据存储器,程序存储器和电可擦写可编程存储器;它们各自有不同的用途。

1. 数据存储器

  数据存储器是一块2KB大小的静态随机存储器(SRAM)。其中一部分空间分配给了通用寄存器和I/O寄存器,其余部分一般用于存储全局变量,堆栈数据和支持动态内存分配。它的存取速度快,但掉电后数据会丢失。

2. 程序存储器

  程序存储器是一块32KB大小的闪存(Flash),其中0.5KB用于引导程序。它可以多次擦写,掉电后数据不会丢失,一般用于存储程序。

3. 电可擦可编程只读存储器

  电可擦写可编程只读存储器(EEPROM)是一块1KB大小的独立数据存储空间。它和程序存储器一样可以用于保存程序运行中的数据,但在掉电后数据不会丢失。

Arduino IDE提供了几个EEPROM的示例,eeprom_write示例将0引脚上的模拟信号转换为数字信号,并将转换结果以字节的形式保存到EEPROM中:

 1 // eeprom_write.ino
 2 #include <EEPROM.h>
 3
 4 int addr = 0;
 5
 6 void setup() {
 7 }
 8
 9 void loop() {
10   int val = analogRead(0) / 4;
11
12   EEPROM.write(addr, val);
13
14   addr = addr + 1;
15   if (addr == EEPROM.length()) {
16     addr = 0;
17   }
18
19   delay(100);
20 }

和eeprom_write示例相反,eeprom_read示例将EEPROM中的数据以字节的形式读出,并打印到串口0上:

 1 // eeprom_read.ino
 2 #include <EEPROM.h>
 3
 4 int address = 0;
 5 byte value;
 6
 7 void setup() {
 8   Serial.begin(9600);
 9   while (!Serial) {
10     ;
11   }
12 }
13
14 void loop() {
15   value = EEPROM.read(address);
16
17   Serial.print(address);
18   Serial.print("\t");
19   Serial.print(value, DEC);
20   Serial.println();
21
22   address = address + 1;
23   if (address == EEPROM.length()) {
24     address = 0;
25   }
26
27   delay(500);
28 }

  与EEPROM相关的Arduino库函数有:

  EEPROM.write(address, val):向EEPROM指定地址写入一个字节的数据

  address:指定数据写入的地址

  val:写入的数据

  EEPROM.read(address):从EEPROM指定地址读出一个字节的数据

  address:指定数据读取的地址

  函数返回读取的一个字节数据

  EEPROM.length():获取EEPROM大小

  函数返回EEPROM的大小

  ATMega328P的EEPROM由3个寄存器控制,EEPROM地址寄存器(EEARH和EEARL)EEPROM数据寄存器EEDR分别用于在写入或读取EEPROM时保存地址信息和数据信息。EEPROM控制寄存器EECR的结构如下图所示:


EEPM1


EEPM0


EERIE


EEMPE


EEPE


EERE

将EEPROM主机写使能位EEMPE置1后,4个时钟周期内将EEPROM写使能位EEPE置1,就可以数据写入EEPROM的指定地址中;向EEPROM读使能位EERE写入1,则可以将EEPROM指定地址的数据读入EEDR寄存器中。

  通过直接访问寄存器改写以上程序为:

 1 // eeprom_write_reg.ino
 2 #include <EEPROM.h>
 3
 4 int addr = 0;
 5 void eeprom_write(int address, byte val);
 6
 7 void setup() {
 8 }
 9
10 void loop() {
11   int val = analogRead(0) / 4;
12
13   eeprom_write(addr, val);
14
15   addr = addr + 1;
16   if (addr == EEPROM.length()) {
17     addr = 0;
18   }
19
20   delay(100);
21 }
22
23 void eeprom_write(int address, byte val) {
24   while (EECR & (1 << EEPE));
25   EEAR = address;
26   EEDR = val;
27   EECR |= (1 << EEMPE);
28   EECR |= (1 << EEPE);
29 }
30
31 // eeprom_read.ino
32 #include <EEPROM.h>
33
34 int address = 0;
35 byte value;
36 byte eeprom_read(int address);
37
38 void setup() {
39   Serial.begin(9600);
40   while (!Serial) {
41     ;
42   }
43 }
44
45 void loop() {
46   value = eeprom_read(address);
47
48   Serial.print(address);
49   Serial.print("\t");
50   Serial.print(value, DEC);
51   Serial.println();
52
53   address = address + 1;
54   if (address == EEPROM.length()) {
55     address = 0;
56   }
57
58   delay(500);
59 }
60
61 byte eeprom_read(int address) {
62   while (EECR & (1 << EEPE));
63   EEAR = address;
64   EECR |= (1 << EERE);
65   return EEDR;
66 }
时间: 2024-10-27 06:56:47

AVR开发 Arduino方法(六) 内存子系统的相关文章

AVR开发 Arduino方法(附二) 故障排除:烧录引导程序

在"内存子系统"一章中我们曾提到,Arduino UNO R3开发板上的ATMega328P有0.5KB的Flash空间用于引导程序:因为有引导程序的支持,Arduino可以使用串口上传程序而无需编程器.一般地,按下Arduino UNO R3开发板上的复位按键,13引脚上的LED快速的闪烁3下,代表引导程序正常启动.如果出现上传程序没有响应或复位时LED没有闪烁,排除硬件故障后,可以考虑重新烧录引导程序. (1) 使用USBasp编程器烧录引导程序 Arduino IDE支持的编程器

AVR开发 Arduino方法(二) 中断子系统

在了解ATMega328P的中断子系统之前,首先要了解中断的概念.你正在看书,这时电话响了,你会怎么做呢?相信大多数人会这样:先标记看到的位置,接完电话回来后继续阅读.这就是一个现实生活中中断的例子,我们把"电话响了"成为中断源.ATMega328P拥有26个中断源,如下表所示: 向量号 程序地址 中断源 中断定义 中断服务程序名称 1 0x0000 RESET 外部电平复位,上电复位,掉电检测复位,看门狗复位 2 0x0002 INT0 外部中断请求0 INT0_vect 3 0x0

AVR开发 Arduino方法(五) 模数转换子系统

模数转换子系统用于将传感器采集的模拟信号转换为数字信号.Arduino UNO R3主处理器ATMega328P的模数转换子系统采用逐次逼近的方式完成模数转换. 使用Arduino库函数进行模数转换十分简单,下面的示例可以将A0引脚上的模拟信号转换为数字信号,并将转换结果打印到串口0上: 1 // ReadAnalogVoltage.ino 2 void setup() { 3 Serial.begin(9600); 4 } 5 6 void loop() { 7 int sensorValue

AVR开发 Arduino方法(一) 端口子系统

Arduino UNO R3使用的主处理器ATMega328P上有3个8位的输入/输出端口,它们分别是PB,PC和PD.Arduino IDE提供的Blink示例可以帮助我们了解端口的数字输出功能: 1 int led = 13; 2 3 void setup() { 4 pinMode(led, OUTPUT); 5 } 6 7 void loop() { 8 digitalWrite(led, HIGH); 9 delay(1000); 10 digitalWrite(led, LOW);

小白学开发(iOS)OC_ set方法的内存管理分析(2015-08-04)

// //  main.m //  set方法的内存管理分析 // //  Created by admin on 15/8/5. //  Copyright (c) 2015年 admin. All rights reserved. // #import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { @autoreleasepool { //p 

【IOS】IOS开发问题解决方法索引(一)

IOS开发问题解决方法索引(一) 1       Xcode工程调试时无法命中断点的问题 若没有勾选LLVM Compiler 1.6 –> CodeGeneration –> Generate Debug Symbols 一项,则程序调试时无法命中断点. 2       Xcode调试时查看变量的几种方法 Xcode如何查看内存中的数据 http://blog.csdn.net/evgd2288/article/details/8995779 Xcode的Debug中查看数据细节的方法 ht

C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)

原文:C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件) 微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C#微信公众号开发系列教程四(接收普通消息) C#微信公众号开发系列教程五(接收事件推送与消息排重) C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件) 第四,第五章已经讲了怎么处理用户发送的消息,本章就来讲讲怎么响应用户的

OC中的属性、方法及内存管理

普通方法:关注(代表)对象可以”干什么”,过程中需要实例变量.-(void)show;输出 … 访问属性    属性:属性专门处理实例变量.(程序执行过程当中)    初始化方法:一创建对象(第一时间),给实例变量赋值.    工厂方法:只一个方法,帮我们解决创建对象问题.初始化对象的问题.工厂方法创建对象最简单.(对象达到一定量级) 补:在类方法中,可以调用类中创建的实例的实例方法或实例变量. 算法.设计模式:是人们总结的一种规律,一种思想. 1.单例模式    是一种特殊的工厂方法.    

Cmdlet开发与学习(六)

之前的内容主要是关于cmdlet开发的,下面要将的内容,是关于在应用程序中集成PowerShell引擎. 运行空间和管道       Runspace类是PowerShell引擎API的重要组成部分,Runspace实例代表一个PowerShell执行引擎实例,其中包含自己的一系列变量,驱动器映射,函数等.这些资源统称为运行空间的"会话状态". 创建并调用Pipeline类的实例,我们就可以在运行空间中使用命令行.Pipeline类实例代表PowerShell命令行对象,其中包含各种命