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

2019-12-06来源: eefocus关键字: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

 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

 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

 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

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 }


关键字:AVR开发  Arduino方法  内存子系统 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic482228.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:AVR开发 Arduino方法(五) 模数转换子系统
下一篇:AVR开发 Arduino方法(七) 嵌入式操作系统FreeRTOS

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

codeblocks+winavr开发avr单片机(atmega16)
在avrfeaks论坛里,有一个帖子是关于在codeblocks环境下(与winavr结合)开发avr单片机的,挺不错的,这里转载一下:I got curious, so I downloaded the current C::B installer. It looks better than when I last used it (a year ago?):- A working installation program, with no need to install graphics packages and stuff (WxWidget, MinGW) separately.- A user manual is now
发表于 2020-01-03
codeblocks+winavr开发avr单片机(atmega16)
AVR开发 Arduino方法(附二) 故障排除:烧录引导程序
在“内存子系统”一章中我们曾提到,Arduino UNO R3开发板上的ATMega328P有0.5KB的Flash空间用于引导程序;因为有引导程序的支持,Arduino可以使用串口上传程序而无需编程器。一般地,按下Arduino UNO R3开发板上的复位按键,13引脚上的LED快速的闪烁3下,代表引导程序正常启动。如果出现上传程序没有响应或复位时LED没有闪烁,排除硬件故障后,可以考虑重新烧录引导程序。(1) 使用USBasp编程器烧录引导程序Arduino IDE支持的编程器有AVRISP mkII,USBtinyISP和USBasp等,这里以USBasp
发表于 2019-12-06
AVR开发 Arduino方法(附二) 故障排除:烧录引导程序
AVR开发 Arduino方法(七) 嵌入式操作系统FreeRTOS
FreeRTOS可以提供任务管理,队列管理,中断管理,资源管理和内存管理等功能,由于占用资源少,它可以运行在Arduino UNO R3开发板上。你可以在https://github.com/greiman/FreeRTOS-Arduino上下载到它,将下载到的FreeRTOS-Arduino-master.zip解压,并将/FreeRTOS-Arduino-master/libraries文件夹下的内容全部复制到Arduino IDE安装目录下的libraries文件夹里就可以使用了。下面是它提供的frBlink示例: 1 // frBlink.ino 2 #include
发表于 2019-12-06
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
发表于 2019-12-06
AVR开发 Arduino方法(四) 串行通信子系统
  Arduino UNO R3主处理器ATMega328P的串行通信子系统可以用于与计算机、外设或其他微控制器进行通信,它支持3种串行通信方式:通用同步/异步收发器,串行外设接口和两线串行接口。1. 通用同步/异步收发器  在串行通信中,波特率用来衡量传输速率的快慢,同步和异步的对象是波特率的时钟信号;同步通信的设备之间需要一条额外的时钟线,也因此同步方式可以提供更高的波特率;这里将以异步为例。  下面的示例可以使通过串口发送给Arduino的数据回显到串口监视器上: 1 // SerialEcho.ino 2 char data; 3  
发表于 2019-12-05
AVR开发 Arduino方法(四) 串行通信子系统
AVR开发 Arduino方法(三) 定时/计数器子系统
脉宽调制的一个典型应用是控制直流电机速度。将直流电机两极分别连接到直流电源的正负两极上,电机会以最快速度运行;要调整电机速度,一个很容易想到的方法是调整直流电源的功率,但在数字系统中还有一个更简单的方式:使用高低电平宽度不一样的脉冲信号快速开关直流电机;因为惯性的作用,电机不会以最快的速度运行。一般来说,高电平在一个脉冲周期中所占宽度更宽时,直流电机速度越快;我们把高电平所占一个脉冲周期的宽度称为占空比。如图所示连接电路,11(PB3/OC2A)引脚通过三极管间接控制直流电机:用Arduino库函数输出一个脉宽调制信号十分简单,下面的示例使得直流电机由慢到快,又由快到慢反复运行: 
发表于 2019-12-05
AVR开发 Arduino方法(三) 定时/计数器子系统
小广播
何立民专栏 单片机及嵌入式宝典

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

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved