二、外部存储:AT24C32存储芯片的使用
AT24C32提供32768位的串行电可擦写可编程只读存储器,组织形式为4096字×8位字长。AT24C32的级联特性允许在同一I2C总线上挂接8个器件,百万次的复写周期和100年的保存年限,并带有写保护功能。
接线图(和RTC DS1307的接法一样):
运行Arduino IDE,打开以下文件:
可以在Arduino IDE中看到以下代码:
- #include <Wire.h>
- #include <AT24Cxx.h>
- #include <RTClib.h>
- AT24Cxx AT24C32(0x50);
- RTC_DS1307 RTC;
- void setup (void){
- //初始化串口
- Serial.begin(9600);
- //初始化I2C
- Wire.begin();
- //初始化RTC
- RTC.begin();
- }
- void loop() {
- //判断是否有新串口数据
- if (Serial.available() > 0) {
- //读取数据
- int instruct = Serial.read();
- switch (instruct) {
- case 'P':
- {
- //先eeprom 指定地址写入数据
- AT24C32.WriteMem(0, 0x04);
- break;
- }
- case 'G':
- {
- char buffer[3];
- //读取三个字节数据
- AT24C32.ReadMem(0, buffer, 3);
- Serial.print(2000 + buffer[2], DEC);
- Serial.print('/');
- Serial.print(buffer[1], DEC);
- Serial.print('/');
- Serial.print(buffer[0], DEC);
- Serial.println();
- break;
- }
- case 'F':
- {
- //获取当前时间信息
- DateTime now = RTC.now();
- char buffer[3];
- buffer[0] = now.day();
- buffer[1] = now.month();
- buffer[2] = now.year() - 2000;
- //写入时间信息到eeprom
- AT24C32.WriteMem(0, buffer, 3);
- break;
- }
- }
- }
- }
复制代码
打开串口监控器,当输入字符“F”时,串口窗口不会有任何反应,但Arduino会把年、月、日信息储存到EEPROM;输入字符“G”,则会把存储的年、月、日信息读取出来。复位Arduino后再次输入字符“G”,仍能把一样的信息读取出来,说明数据没有丢失。
输入字符“P”,再输入字符“G”,可以看到日期被强制设定为4号
下面我们来看一下代码:
#include <Wire.h>#include <AT24Cxx.h>
当设备要使用I2C总线时,必须包含Wire.h 这个文件。而AT24Cxx.h 则是AT24Cxx 系列通用的头文件。
AT24Cxx AT24C32(0x50);
创建一个AT24Cxx 实例,而0x50则是AT24C32的地址,上面介绍AT24C32 时提到这款芯片可以在I2C总线上挂接8个器件,那么我们如何区分开来这八个器件呢? AT24C32又是如何知道哪些数据是发给自己而不是别的总线上的器件呢?
原来,AT24C32上还配备了三个地址选定管脚,A2、A1、A0。而高四位的地址已经固定为1010,A2、A1、A0三个地址脚的连接方式分别决定了后3位的数值。I2C模块上的AT24C32的A2、A1、A0 都接到了地,所以得出的7位地址为101 0000,写成16进制的话为0x50。
char buffer[3];
buffer[0] = now.day();
buffer[1] = now.month();
buffer[2] = now.year() - 2000;
AT24C32.WriteMem(0, buffer, 3);
这几行的代码的意思是把年、月、日信息写到EEPROM上,我们首先看WriteMem 这个方法,它是专门用来写(保存)数据到EEPROM的,它接收三个参数,第一个是地址,EEPROM内部是通过地址来区分数据存储位置的,例如AT24C32,它具有4096字×8位字长的存储能力,则地址范围则是0 - 4096。这里第一个参数设的是“0”,他可以更改为0 - 4096中的任意一个数。第二个参数为需要写到存储器的数据块的开头地址,注意不是数据本身,而是数据的地址,比较容易理解的实现方式是声明一个数组,然后把数组名作为这个参数(数组名则为该数据块的起始地址)。最后一个参数是要写入的字节数,它不能大于数据块的大小(即数组的大小)。
AT24C32.WriteMem(0, 0x04);
这行代码的意思是把一字节的数据(0x04)写到EEPROM的地址为0的空间上,这里大家会发现这个方法的名字跟前面的一模一样,这是面向对象编程中一个叫重载的特性,这项特性允许创建函数名称相同但功能的输入输出类型不同的子程序,当你只要存储一个字节的数据时比较方便。
char buffer[3];AT24C32.ReadMem(0, buffer, 3);
这两行代码的意思是从EEPROM上读取三个字节的数据,并保存到缓冲数组上。ReadMem这个方法是专门把数据从EEPROM上读取出来。它接收三个参数,第一个是地址,第二个是缓冲块的开头地址(数组名),最后一个参数是要读取的字节数,它不能大于缓冲数据块的大小(即数组的大小)。
第二部分到此结束:-)
|