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的大小

 

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

 

 

EEPM1

EEPM0

EERIE

EEMPE

EEPE

EERE

EEPROM主机写使能位EEMPE1后,4个时钟周期内将EEPROM写使能位EEPE1,就可以数据写入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 }
posted @ 2017-09-17 09:37  Lets_Blu  阅读(1330)  评论(0编辑  收藏  举报