ESP32学习笔记
Arduino环境
书接上回,在完成基础的传感器和执行器模块测试后,接下来要完成的就是对EEPROM的操作。
在本实训平台中已经集成了一个AT24C256的存储器芯片,因此只需要将ESP32 和 AT24C256连接就形成一个外置EEPROM存储。
IIC协议的EEPROM单模块测试
AT24C256只读存储器介绍
- 特性:
- 内部组成32K * 8存储单元
- 2线串行接口
- 双向数据传送协议
- 具有64字节页写模式
- 斯密特触发,滤波输入抑制噪声
-
引脚介绍
-
A0、A1、A2:地址选择输入端,串行总线结构中可以连接4个AT24C256芯片。用A0、A1来区分各IC。A0、A1悬空时为0。
-
SCL:串行时钟输入。上升沿将SDA上的数据写入存储器,下降沿将存储器中的数据发送到SDA上。
-
SDA:双向串行数据输入输出口。用于存储器和单片机之间的数据交换。
-
WP:写保护输入。WP置低电平时允许写操作,WP置高电平时禁止一切写操作,不连接时默认接地置低电平。
-
VCC:5.0V(VCC=4.5V~5.5V)
2.7V(VCC=2.7V~5.5V)
1.8V(VCC=1.8V~3.6V)
-
GND:地
-
-
工作原理
-
时钟和数据传送:
一般情况下,SDA被外部设备拉高。只有SCL为低电平的时候,SDA上的数据变化表示要传送数据。SCL为高时SDA的变化表示状态变化。
-
开始状态(START)
SCL为高时,SDA由高到低表示数据传输开始,之一状态必须在所有操作之前。
-
结束状态(STOP)
SCL为高时,SDA由低到高表示数据传输结束。
-
应答状态(ACK)
所有的地址和数据都是以8位的形式串行传送给存储器或者从存储器中读出。存储器在第9个时钟周期SDA发零信号表示已经接收到8位数据。
-
时序图:
-
- AT24C256外围电路原理图
-
设备地址:
EEPROM进入开始状态后,需要一个8位的地址字来选择芯片进行读写操作。设备地址字由5位0 ,1组成的命令字和两位地址选择位A1 A0和一位读/写操作位构成。对于AT24C256,命令字为**10100**。同一串行线上可以连接4个设备,由A1、A0地址线区分,如果只有1个,那就都置0。最低位R/W,1表示读操作,0表示写操作。
格式:
-
写方式
-
写字节
向AT24C256发送设备地址字后,需要发送2个8位地址来选择要写数据的地址,AT24C256收到地址后应答一个零信号,然后根据时钟写8位数据到AT24C256。存储器接收到数据后返回一个应答信号。写数据结束后,AT24C256进入内部计时的写周期。写循环过程中所有的输入都不能进行,直到写结束EEPROM才开始响应。
-
写页
AT24C256 具有64字节作为一页的写页功能,可以一次性写入一页。写页的初始化过程与写字节的方法基本相同。不同的是写入一个字节后,微控制器不发停止状态命令,而是在应答信号后,接着输入63个字节。每一个字节接收到后,EEPROM照样输出一个为零的应答信号。因为一页只有64个单元,所以数据字的地址低6位接收到一个字节后会自动加1,高位地址不变,即页地址不变。当内部产生的地址到页边界时,接下来的字节要放至该页的开始。如果发送至E2PROM的数据超过 64字节,则最早写的字节将被覆盖。
-
-
读方式
-
当前地址读
内部数据的地址保持在最后的读写操作地址加1上,只要芯片有电源供应,这个地址就一直保持。读到EEPROM最后一个字节后又回到最开始的位置。
-
随机读
随机读要先向EEPROM写入一个地址
-
读串
既可以是当前地址读也可以是随机地址读,微控制器接收到一个字后回应一个应答信号。一旦EEPROM接收到应答信号,地址加一,接着输出下一个字节。微控制器接收到数据后不回应答信号时,表示读过程结束。
-
使用外置AT24C256 使用IIC总线实现EEPROM的读写操作
实验效果:
通过杜邦线连接AT24C256在本实训平台上预留的EE_SCL和EE_SDA引脚即可实现对EEPROM芯片的数据写操作和数据读操作。
接线:ESP32的IO2 和 IO22为我所用的库文件中定死的用于连接AT24C256的SDA 和 SDL,因此在进行测试的时候经历了较长的找bug时间,后续在VS Code环境中使用C语言进行开发的时候会再写一篇C版本的EEPROM使用。
实验代码:
#include <AT24C256.h>
AT24C256 eeprom(0x50);
void setup() {
char message[30];
char writemessage[] = "EEPROM test";
Serial.begin(9600);
Serial.println("reading eeprom");
eeprom.read(0, (uint8_t*) message, sizeof(message));
Serial.println(message);
eeprom.write(0, (uint8_t*)writemessage, sizeof(message));
Serial.println("wrote eeprom");
Serial.println("reading eeprom");
eeprom.read(0, (uint8_t*) message, sizeof(message));
Serial.println(message);
}
void loop() {
// put your main code here, to run repeatedly:
}