ESP8266 - Arduino 知识整理

整理在做毕业设计过程中学到的知识,经常使用的文档、网站:

  • ESP8266 Arduino 核心开发文档

  • 太极创客 ESP8266开发资料

  • Random Nerd Tutorials

ESP8266 - Arduino 知识整理_第1张图片

  下表显示了丝印标签和GPIO编号之间的对应关系、最适合使用的引脚,以及需要谨慎使用的引脚。用“√ ”标出的引脚可以使用。“※”可以使用,但是需要注意:它们在启动时有意料之外的行为。“×”的引脚不建议用作输入或输出。

丝印标签 GPIO 输入 输出 Notes
D0 GPIO16 × 没有PWM,不支持I2C 启动时高电平,用来唤醒深度睡眠
D1 GPIO5 SCL
D2 GPIO4 SDA
D3 GPIO0 上拉 连接到FLASH,如果下拉会启动失败
D4 GPIO2 上拉 连接到板载LED,如果下拉会启动失败
D5 GPIO14 SPI( SCLK )
D6 GPIO12 SPI( MISO)
D7 GPIO13 SPI( MOSI )
D8 GPIO15 SPI( CS ) 如果上拉,启动失败
RX GPIO3 RX引脚 启动时高电平
TX GPIO1 × 启动时高电平,输出debug信息;
如果拉低则启动失败
A0 ADC0 模拟输入 × 分辨率:10bit

1. 引脚

1.1 启动时使用的引脚

​​ 如果某些引脚被拉低或高,ESP8266 启动会被阻止。以下列表显示启动时引脚的状态:

GPIO 状态
GPIO0 拉低,启动失败
GPIO1 拉低,启动失败
GPIO2 拉低,启动失败
GPIO3 启动高电平
GPIO9 启动高电平
GPIO10 启动高电平
GPIO15 拉高,启动失败
GPIO16 启动高电平
1.2 启动时输出高电平的引脚

​ ​ 当 ESP8266 启动时,某些引脚会输出 3.3V。如果有继电器或其他外设与这些 GPIO 相连可能会有问题。以下 GPIO 在引导上输出高信号:GPIO1、GPIO3、GPIO9、GPIO10、GPIO16。 继电器通常与 GPIO5 和 GPIO4相连。

1.3 RST 引脚

 ​ 当 RST 引脚拉低时,ESP8266 将重置。这与按下机载RST按钮相同。

1.4 GPIO0

 ​ 当 GPIO0 被拉低时,它会将 ESP8266 设置为引导加载器模式。这与按下机载FLASH/ BOOT按钮相同。

1.5 GPIO16

 ​ 用于从深度睡眠中唤醒 ESP8266。要从深度睡眠中唤醒 ESP8266,GPIO16 应连接到 RST 引脚。

1.6 中断引脚

除GPIO16 都可设置中断,慎用、不用3(D3连接到FLASH)

2. ADC输入电压范围

  • ESP8266 开发板的 ADC 电压范围:0 - 3.3V(例如:ESP8266 12-E NodeMCU Kit、WeMos D1 Mini)

  • ESP8266 芯片中的 ADC 电压范围:0-到 1V(例如:ESP-07 芯片、ESP-12E 芯片)

3.中断

attachInterrupt (digitalPinToInterrupt(GPIO), ISR, mode)

  • digitalPinToInterrupt(GPIO) :中断引脚,除GPIO16都可以设置中断。
    eg: digitalPinToInterrupt(14)

  • ISR : 中断服务例程。功能应尽可能简单,以便处理器快速恢复主程序的执行。最好的方法是使用全局变量、在 loop() 中检查并清除该标志并执行代码。

  • mode : 中断模式。

    • CHANGE:引脚电平值改变时触发中断
    • FALLNG:引脚电平从高到低时触发中断
    • RISING:引脚电平从低到高时触发中断

ISR 需要有 ICACHE_RAM_ATTR 修饰,如果没有该属性会在attachInterrupt部分报错。如下是HX711的一个中断实例:

//HX711的中断处理函数
 ICACHE_RAM_ATTR void dataReadyISR() {
   if (LoadCell.update()) {
     newDataReady = 1;
   }
 }

※Notes:

  1. 中断过程中不能调用delay( )或yield( ),或调用内部使用delay()或yield( )的任何例程。
  2. 长时间运行(> 1ms)的中断任务将导致程序不稳定或崩溃。如果中断被长时间运行的中断阻塞,WiFi和核心的其他部分可能会变得不稳定。如果有很多事情要做,可以设置一个易失的全局标志,以便主循环loop()检查或者使用scheduled 函数(在安全的情况下在中断上下文之外调用该函数)来进行长时间运行的工作。
  3. 内存操作是危险的,应该在中断中避免。尽量减少对new或malloc的调用。因为如果内存被分割,可能需要很长的运行时间。出于同样的原因,realloc和free绝对不能被调用,也不能使用任何调用free或realloc本身的例程或对象。这意味着使用String、std:string 、std::vector和其他可调整大小的连续内存的类时必须非常小心(确保不改变字符串,不添加vector元素,等等)。

4.深度睡眠

  1. 使用 ESP.deepSleep(μs) 将 ESP8266 置于深度睡眠模式,通过传参设置睡眠时间。GPIO 16 必须连接到RST引脚才能将ESP8266唤醒。ESP8266 - Arduino 知识整理_第2张图片
  2. 将ESP8266置于深度睡眠模式,无限期使用ESP.deepSleep(0)。当 RST 引脚收到低信号时,ESP8266 将唤醒。
  3. 睡眠模式有三种不同类型:modem sleeplight sleepdeep sleep。下表显示了每个模式之间的差异。ESP8266 - Arduino 知识整理_第3张图片
  4. 唤醒来源
    • 定时器唤醒:ESP8266在预先定义的时间段后自行唤醒
    • 外部唤醒:ESP8266 在按 RST 按钮时唤醒(ESP8266 重新启动)
// ESP8266 Deep sleep mode example
void setup() {
  Serial.begin(115200);
  Serial.setTimeout(2000);

  // Wait for serial to initialize.
  while(!Serial) { }

  ///深度睡眠模式,直到RESET引脚连接到一个低电平
  Serial.println("I'm awake, but I'm going into deep sleep mode until RESET pin is connected to a LOW signal");
  ESP.deepSleep(0); 
}

void loop() {

}

5. 串口

  该Serial对象的工作方式与常规Arduino相同。除了硬件FIFO(用于TX和RX的128字节)之外,Serial还有一个可定制256字节的RX缓冲区。用户可以通过在begin()之前调用函数setRxBufferSize(size_t size)更改RX缓冲区的大小。size参数至少应足够大以容纳读取接收到的所有数据。
  接收是由中断驱动的,但发送轮询和繁忙等待。阻塞行为如下:如果字节数适合TX FIFO(先入先出队列,常见的数据结构,不懂自行搜索)中的当前空间,则::write()调用不会阻塞。如果TX FIFO已满,则调用将阻塞,并等待直到有空间再向其中写入更多字节,直到所有字节被写入为止。换句话说,当调用返回时,所有字节均已写入TX FIFO,但这并不意味着所有字节均已通过串行线路发送出去。
  read()调用不会阻塞,即使没有可供读取的字节也不会阻塞。但是 readBytes()调用会阻塞,直到读取的字节数符合传入的参数所需的字节数为止。
   flush()调用会阻塞,等待TX FIFO为空再返回。

※Notes:ESP8266 - Arduino 知识整理_第4张图片
  HardwareSerial类有SerialSerial1两个对象。
  Serial使用UART0 (TX 、RX),该UART0映射到GPIO1(TX)和GPIO3(RX)引脚。通过在Serial.begin之后调用Serial.swap()可以将串口重新映射到GPIO15(TX(D8))和GPIO13(RX(D7)) 。再次调用swap将UART0映射回GPIO1和GPIO3。
  Serial1使用UART1,TX引脚为GPIO2(D4)。UART1不能用于接收数据,因为通常它的RX引脚被用于闪存芯片连接。要使用Serial1,需要配置Serial1.begin(baudrate)
如果未使用Serial1并且未交换Serial-UART0的TX可以通过在Serial.begin之后调用Serial.set_tx(2)或直接通过Serial.begin(baud,config,mode,2)将UART0的TX引脚映射到GPIO2(D4)。

  默认情况下,调用Serial.begin(),WiFi库的诊断输出是禁用的。要启用调试输出,需要调用 Serial.setDebugOutput(true)。要将调试输出重定向Serial1 ,请调用Serial1.setDebugOutput(true)
  使用Serial.setDebugOutput(true)启用printf()功能的输出。
  SerialSerial1对象支持5,6,7,8个数据位,奇、偶、无校验位,和1、2个停止位。通过调用Serial.begin(baudrate, SERIAL_8N1)Serial.begin(baudrate, SERIAL_8N1)设置预期的工作模式。默认配置模式为SERIAL_8N1。可选的模式有SERIAL_[5 6 7 8][ N E O][1 2]。例如:SERIAL_8N1为8位数据位,无校验位,1位停止位。

6. 文件系统

  保留了自己用到的,如果需要详细了解文件系统可以配合翻译软件查看ESP8266-Arduino Core 官方文档
  

6.1 FLASH布局

​  文件系统与程序存储在同一FLASH中,编写新 sketch 不会修改文件系统内容。这允许使用文件系统来存储 sketch 数据,配置文件或Web服务器的内容。下图说明了Arduino环境中的 Flash 布局:文件系统
要在sketch中使用文件系统功能,需要添加以下内容:

#include "FS.h" 	  // SPIFFS is declared
#include "LittleFS.h" // LittleFS is declared
6.2 SPIFFS和LittleFS

在ESP8266上有两个板载Flash的文件系统:SPIFFS、LittleFS

  • SPIFFS 是原始文件系统,适合空间和RAM受限的应用程序,但是不是真正的目录支持, 在未来版本将会逐渐弃用。

  • LittleFS 支持实际的目录,大多数操作的速度要比 SPIFFS 快很多倍,但文件系统和每个文件的开销更大(最小4K,而SPIFFS最小256字节)。

  • SPIFFSLittleFS 的函数调用接口 API 是兼容的,但在 flash 上的实现并不一样。如果在 LittleFS 下挂载 SPIFFS 可能会导致格式化,不会保留任何文件,反之亦然。

   从这两个文件系统返回的对象 FileDir 是一样的,将应用程序从SPIFFS 转换为LittleFS,只需将 SPIFFS.begin() 更改为 LittleFS.begin()SPIFFS.open() 改为 LittleFS.open(),其余代码可以保持不变。

6.2.1 SPIFFS文件系统限制

   ESP8266的SPIFFS实现必须适应芯片的限制,其中包括有限的RAM。 SPIFFS是为小型系统设计的,但这是以简化和限制为代价的。
​   1、SPIFFS不支持目录,它只存储一个“扁平”的文件列表。但是与传统文件系统相反,文件名中允许使用'/',因此处理目录列表 ( eg:openDir("/website") )的功能基本是过滤文件名,并保留以/website/请求的前缀开头的文件名。
​   2、文件名总共不能超过32个字符。'\0'为C字符串终止保留的,因此我们剩下31个可用字符。这意味着要尽量使用短文件名,而不要使用深度嵌套的目录,因为每个文件的完整路径(包括目录,'/'字符,基本名称,点和扩展名)最多不能超过31个字符。例如,文件名 /website/images/bird_thumbnail.jpg是34个字符,如果使用,将导致一些问题。例如:在另一个文件以相同的前31个字符开头的情况下使用exists()

Notes:很容易达到限制,并且如果忽略该问题。由于在编译或运行时都不会出现错误消息,因此可能不会引起注意。有关SPIFFS实现内部细节的更多信息,请参见 SPIFFS自述。

6.2.2 LittleFS文件系统的局限性

  ESP8266的LittleFS实现支持最多31个字符+以零结尾的文件名(即 char filename[32]),以及空间允许的尽可能多的子目录。
  如果不存在“ /”,则假定文件名位于根目录中。
  在子目录中打开文件需要指定文件的完整路径eg: open("/sub/dir/file.txt");当在子目录中创建文件时,会自动创建子目录;当删除子目录中的最后一个文件时,会自动删除子目录本身。现有的SPIFFS文件系统中没有mkdir() 方法。
  与SPIFFS不同,实际文件描述符是根据应用程序的请求分配的,因此在内存不足的情况下,可能无法打开新文件。相反,这也意味着只有使用的文件描述符实际上会在堆上占用空间。
  由于存在目录,因此openDir方法的行为不同于SPIFFS。遍历a时, SPIFFS返回“子目录”中的文件Dir::next()(实际上并不是子目录,而只是名称中带有“ /”的文件),而LittleFS仅返回特定子目录中的文件。

6.3 将文件上传到文件系统

  ESP8266FS 是一个集成到Arduino IDE中的工具。它在菜单栏“工具”中添加了一个菜单项,用于将sketch的 data 目录的内容上传到ESP8266 Flash文件系统中。ESP8266LittleFSESP8266FS 等效,使用方法一样,具体步骤如下:

  • 下载 ESP8266FS、ESP8266LittleFS

  • 在 Arduino 的工作目录下,创建 tools 目录

  • 压缩包解压到 tools 中,如果要升级,直接覆盖现有的就可以

  • 重新启动Arduino IDE,然后打开、创建一个sketch

  • 转到sketch目录(选择“sketch”>“显示sketch文件夹”)

  • 在sketch文件夹下中创建一个名为data的目录,将需要上传的文件放入其中

  • 选择好开发板、端口,并且关闭串行监视器 (上传文件过程中若开着串口监视器会报错)

  • 上传sketch,选择 “工具> ESP8266 sketch Data Upload”,将文件上传到ESP8266 Flash文件系统中。完成后,IDE状态栏将显示消息SPIFFS Image Uploaded

7. ESP8266常用库

7.1 SPI

  SPI库支持整个Arduino SPI API,包括事务,包括设置阶段(CPHA)。目前尚不支持设置时钟极性(CPOL)(SPI_MODE2和SPI_MODE3不起作用)。
  常用的SPI引脚为:
   MOSI = GPIO13 (D7)
   MISO = GPIO12 (D6)
   SCLK = GPIO14 (D5)
  有一个扩展模式,将普通引脚交换为SPI0硬件引脚。通过在调用SPI.begin()之前调用SPI.pins(6, 7, 8, 0) 来启用此功能。引脚将变为:
   MOSI = SD1
   MISO = SD0
   SCLK = CLK
   HWCS = GPIO0
  此模式与控制器共享SPI引脚,该控制器从FLASH读取程序代码,并由硬件仲裁器控制(FLASH始终具有更高的优先级)。在这种模式下,CS将由硬件控制,因为无法使用GPIO处理CS线路,实际上并不知道仲裁器会何时将授予访问总线的权限,因此必须让它自动处理CS。

你可能感兴趣的:(毕业设计,单片机,嵌入式硬件)