vb利用串口读取数据并画图_进阶教程4 EEPROM 读写、清零与串口数据流

本文介绍了Arduino中EEPROM的使用,作为电可擦可编程只读存储器,EEPROM在智能设备中用于存储设置参数,如空调温度、风力等。与Flash不同,EEPROM支持运行时修改并具有更高的擦写次数。文中通过示例代码展示了如何进行读写操作,并提供了清零EEPROM的方法。此外,还讨论了EEPROM与Flash的区别,以及在Arduino上的应用。
摘要由CSDN通过智能技术生成

本专栏内容经修订后,已在豆瓣阅读集结成书出版:

3694bef187de8af4b439cdaa78f05b5b.png
https://read.douban.com/ebook/106875966/​read.douban.com

EEPROM (Electrically Erasable Programmable Read-Only Memory),电可擦可编程只读存储器 ,它是一种掉电后数据不丢失的存储器。

在Arduino开发设计中,非常重要的存储介质。比如,作为智能空调的控制板,关闭空调后,我们希望空调存储关闭前设置的温度、风力。此时可以把设置参数写入EEPROM,再次开启时读取。再如,小型气象站,利用它暂存气象数据,定时通过GSM或者Wi-Fi,发送到服务器,不用长时间开启通信模组,非常省电。

但是Arduino 上的EEPROM不是Flash,后者用于存储程序,前者用户暂存数据,共同点时掉电后,数据都不会消失。 它们之间有什么区别呢?这要从“史前”的ROM讲起。

最初的ROM 是不能编程的,出厂什么内容就永远什么内容。后来出现了PROM,可以写入一次,但要是写错了,只能换一片,自认倒霉。

人类文明不断进步,终于出现了可多次擦除写入的EPROM。不过,每次擦除要把芯片拿到紫外线上照一下。试想一下,你往单片机上写入一个程序后,发现有个小地方要改,为此你要把单片机放紫外灯下照半小时,然后才能再下一次,这么折腾一天也改不了几次。

最终,可以随意修改的 EEPROM 出现了,拯救了一大批程序员。很多人将它与FLASH闪存相比较,实际上FLASH也是EEPROM一种。为了方便区分,我们指EEPROM都是狭义的EEPROM,与FLASH的区别如下:

  1. FLASH 按扇区操作,EEPROM则按字节操作
  2. FLASH 写入时间长,EEPROM写入时间短
  3. FLASH 擦写次数少(TLC 200次 ~ SLC 10000次),EEPROM次数多(1,000,000次)
  4. FLASH 电路结构简单,成本低,EEPROM工艺复杂,成本高
  5. 运行时,EEPROM可以修改,FLASH则不行。因此EEPROM可以存储一些参数,FLASH 存储程序代码和不需修改的数据。

Arduino 上既有FLASH,也有EEPROM。存放程序的区域就是FLASH,Arduino Uno 的空间大小为32KB,而存储一些需要随时修改,但又能掉电保存的数据,比如:数字收音机的频率、智能家居各模块的开关状态等,则放在EEPROM,空间大小为1KB。

EEPROM 的操作,官方提供了8个示例,我们先看看最基本的三个 Write、Read、Clear示例。

71d70b44eb5bb60d7ed0304c03e44c74.png

先对 eeprom_write 程序略微修改一下(程序22.1):

/*
 程序22.1
 作者:Ardui.co
 效果:EEPROM 写入数据
*/
#include <EEPROM.h>
int addr = 0; //初始化地址变量
void setup() {
 pinMode(13, OUTPUT);
}
void loop() {
 int val = analogRead(0) / 4;  //从A0读取结果0~1023,转换为0~255,空载输入为随机数
 EEPROM.write(addr, val); //按照 EEPROM 地址,写入数值
 if (addr <= EEPROM.length()) {  // 如果地址达到末尾,从头开始
 addr = addr + 1; //前一个地址写入数据后,进入下一个地址
 }
 else {
 digitalWrite(13, HIGH); // 全部写入完毕,点亮板载LED
 }
 delay(10);//延时100ms,注意每次写入需要3.3ms,因此不能少于4ms;
}

EEPROM.write(addr, val) 是根据地址来写入数据的:addr:写入字节的地址,整数变量;val:写入的字节,范围0 ~ 255。

现在反过来把这些数据从EEPROM读出来(程序22.2):

/*
 程序22.2
 作者:Ardui.co
 效果:EEPROM 读取数据
*/
#include <EEPROM.h>
int address = 0;
byte value;
void setup() {
 Serial.begin(9600);
}
void loop() {
 value = EEPROM.read(address);
 Serial.print(address);
 Serial.print("t");
 Serial.print(value, DEC);
 Serial.println();
 address = address + 1;
 if (address == EEPROM.length()) {
 address = 0;
 }
 delay(500);
}

打开串口监视器,可以看到刚才写进入的随机数据:

7875944b3bc254f05abcb07004697d37.png

EEPROM一般用于存储设置参数等数据,如果我们想把设备RESET,很简单设置一个Clear程序即可(程序22.3):

/*
  程序22.3
 作者:Ardui.co
 效果:EEPROM 清零
*/
#include <EEPROM.h>
void setup() {
 pinMode(13, OUTPUT);
 for (int i = 0 ; i < EEPROM.length() ; i++) {
 EEPROM.write(i, 0);
 }
 digitalWrite(13, HIGH);
}
void loop() { // 这循环很闲,啥事情都不用干
}

现在让Arduino不停地从0号地址位开始的读取EEPROM,把读取到的数值输出到串口监视器上。如果向串口监视器输入数字,更新从0号地址位开始的EEPROM信息。并间接的更新了输出到监视器上的数值。

由于官方EEPROM 每次只能写入或读取一个地址位,因此我们设置了两个函数 EEPROM_write 与 EEPROM_read,形参跟官方一样,但可以连续读取或写入(程序22.4):

/*
 程序序1.22.4
  作者:Ardui.co
效果:读取串口数据流,写入EEPROM
*/
#include <EEPROM.h>
#define EEPROM_write(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) EEPROM.write(address+i, pp);}
#define EEPROM_read(address, p) {int i = 0; byte *pp = (byte*)&(p);for(; i < sizeof(p); i++) pp=EEPROM.read(address+i);}
unsigned long incomingByte = 0; // 定义无符号长整数型变量incomingByte初始值为0
unsigned long incomingByteTemp = 0;
void setup() {
 Serial.begin(9600); // 打开串口,设置数据传输速率9600
}
  
void loop() {
 if (Serial.available() > 0) {
 incomingByte = Serial.parseInt(); //读取串口传入的下一个有效整数,把该整数赋值给incomingByte变量
 EEPROM_write(0, incomingByte) //把incomingByte变量从0地址位开始写入EEPROM
 }
 if(incomingByte != incomingByteTemp) {
 EEPROM_read(0, incomingByte) //从0地址位开始读取EEPROM,把值写入变量incomingByte
 Serial.println(incomingByte); //通过串口输出
 incomingByteTemp = incomingByte;
 delay(1000);
 }
} 

串口命令 Serial.parseInt() 的作用是查找传入的串行数据流中的下一个有效整数。Serial.read()只能每次读取一个字节,Serial.parseInt() 一次能读取一个数据流。

byte *pp=(byte*)&p 的意思是:定义了一个字节型数组指针pp,将它指向了变量 p 。(byte*) 是为了将&p 强制转换为字节型指针,以便赋值给*pp 。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值