一、ESP8266与EEPROM
1、写数据:
/*
 * 功能描述:该代码向EEPROM写入100字节数据
 */
#include <EEPROM.h>
int addr = 0; //EEPROM数据地址
void setup() 
{
  Serial.begin(9600);
  Serial.println("");
  Serial.println("Start write");
  EEPROM.begin(100);  //申请size大小的内存大小
  for(addr = 0; addr<100; addr++)
  {
    int data = addr;
    EEPROM.write(addr, data); //写数据
  }
  EEPROM.end(); //写入flash并释放内存空间  保存更改的数据
  Serial.println("End write");
}
void loop() 
{
}2、读数据:
/*
 * 功能描述:该代码从EEPROM读取100字节数据
 */
#include <EEPROM.h>
int addr = 0;
void setup() 
{
  Serial.begin(9600);
  Serial.println("");
  Serial.println("Start read");
  EEPROM.begin(100); 
  for(addr = 0; addr<100; addr++)
  {
    int data = EEPROM.read(addr); //读数据
    Serial.print(data);
    Serial.print(" ");
    delay(2);
  }
  //释放内存
  EEPROM.end();
  Serial.println("End read");
}
void loop() 
{
}3、清除数据:
/*
   EEPROM Clear
   Sets all of the bytes of the EEPROM to 0.
   This example code is in the public domain.
*/
#include <EEPROM.h>
void setup() {
  EEPROM.begin(100);
  // write a 0 to all 100 bytes of the EEPROM
  for (int i = 0; i < 100; i++) {
    EEPROM.write(i, 0);
  }
  //释放内存
  EEPROM.end();
}
void loop() {
}4、结构体操作:
/*
 * 功能描述:eeprom结构体操作
 */
#include <EEPROM.h>
#define DEFAULT_STASSID "danpianjicainiao"
#define DEFAULT_STAPSW  "boge"
struct config_type
{
  char stassid[32];
  char stapsw[64];
};
config_type config;
/*
 * 保存参数到EEPROM
*/
void saveConfig()
{
  Serial.println("Save config!");
  Serial.print("stassid:");
  Serial.println(config.stassid);
  Serial.print("stapsw:");
  Serial.println(config.stapsw);
  EEPROM.begin(1024);
  uint8_t *p = (uint8_t*)(&config);
  for (int i = 0; i < sizeof(config); i++)
  {
    EEPROM.write(i, *(p + i));
  }
  EEPROM.commit();
}
/*
 * 从EEPROM加载参数
*/
void loadConfig()
{
  EEPROM.begin(1024);
  uint8_t *p = (uint8_t*)(&config);
  for (int i = 0; i < sizeof(config); i++)
  {
    *(p + i) = EEPROM.read(i);
  }
  EEPROM.commit();
  Serial.println("-----Read config-----");
  Serial.print("stassid:");
  Serial.println(config.stassid);
  Serial.print("stapsw:");
  Serial.println(config.stapsw);
}
/*
*初始化
*/
void setup() {
  ESP.wdtEnable(5000);
  strcpy(config.stassid, DEFAULT_STASSID);
  strcpy(config.stapsw, DEFAULT_STAPSW);
  saveConfig();
}
/*
*主循环
*/
void loop() {
  ESP.wdtFeed();
  loadConfig();
}
二、SPI通信:
1、概述:
 串行外设接口(Serial Peripheral Interface),高速、全双工、同步通信总线(同一时刻只有一主一从进行通信),四线(MISO:主入从出;MOSI:主出从入;SCK:同步时钟信号;SS或CS:片选使能)。(Quad SPI=2Dual SPI=4标准SPI)。
2、ESP8266 SPI类库成员函数:
SPI.h头文件中,该类库只提供主设备API
- SPI.begin()初始化SPI通信;无参,无返回值;
- SPI.end()关闭SPI通信;无参,无返回值;
- SPI.setBitOrder(order)设置数据传输顺序;- 参数(order):- ~ LSBFIRST,低位在前;
- ~ MSBFIRST,高位在前;
 
- 无返回值;
 
- 参数(order):
- SPI.setClockDivider(divider)设置通信时钟(由系统时钟分频)- 参数(divider):- ~ SPI_CLOCK_DIV2, 2分频;
- ~ SPI_CLOCK_DIV4, 4分频;
- ~ SPI_CLOCK_DIV8, 8分频;
- ~ SPI_CLOCK_DIV16, 16分频;
- ~ SPI_CLOCK_DIV32, 32分频;
- ~ SPI_CLOCK_DIV64, 64分频;
- ~ SPI_CLOCK_DIV128, 128分频;
 
- 无返回值;
 
- 参数(divider):
- SPI.setDataMode(mode)设置数据模式- 参数(mode):- ~ SPI_MODE0; 即:CPOL=0,CPHA=0
- ~ SPI_MODE1; 即:CPOL=0,CPHA=1
- ~ SPI_MODE2; 即:CPOL=1,CPHA=0
- ~ SPI_MODE3; 即:CPOL=1,CPHA=1
 
- 无返回值
- 补充:四种模式,即SPI相位(CPHA)和极性(CPOL)分别为0或1;- CPOL:即SPI空闲时,SCLK的电平(1高,0低);
- CPHA:即SPI在SCLK的第几个边沿开始采样(0第一个,1第二个);
 
 
- 参数(mode):
- SPI.transfer(val)传输1B的数据。全双工,发1B收1B数据
- SPI.transfer16(val)传输2B数据,从机返回2B作为返回值;
- SPI.transferBuf(buf,count)传输一个缓冲区数据,参数为发送的缓冲区buf(- uint8_t*数据),count位缓冲区大小,无返回值(但从机传输来的数据会替换掉buf缓冲区的数据)
- SPI.pins(sck,miso,mosi,ss)切换SPI引脚映射,需在- SPI.begin()前调用
3、SPI寄存器:
所有SPI设置都是由Arduino SPI控制寄存器(SPCR)决定。该寄存器就是MCU内存的一个字节,可读写。寄存器提供服务:控制、数据、状态。
- 控制寄存器(SPCR): - 8位,(如单片机的中断允许控制寄存器IE、中断优先级控制寄存器IP、定时器/计数器控制寄存器) 
- 数据寄存器(SPDR): - (如串行口锁存器SBUF,仅hold住一个字节) 
- 状态寄存器(SPSR): -  根据多种微控制器的条件改变其状态 
三、Ticker —ESP8266定时库
1、概述:
- 用于规定时间后调用函数;
- 一个方法的示例(为了说明三个参数时的意义,两个参数时好理解)
/**
 * 每隔xx毫秒周期性执行
 * @param seconds 秒数
 * @param callback 回调函数
 */
void attach_ms(float seconds, callback_function_t callback);
/**
 * 每隔xx毫秒周期性执行
 * @param seconds 秒数
 * @param callback 回调函数
 * @param arg 回调函数的参数
 */
void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)- 不建议使用Ticker回调函数来阻塞IO操作(网络、串口、文件);可以在Ticker回调函数中设置一个标记,在loop函数中检测这个标记;
- 对于arg,必须时char, short, int, float, void* , char* 之一;
2、示例:
/**
 * 代码功能:板载LED开始0.3秒闪,闪20次开始以0.1秒快闪,总共闪120次后最后常亮 
 */
#include <Ticker.h>
Ticker flipper;
int count = 0;
void flip() {
  int state = digitalRead(LED_BUILTIN);  // get the current state of GPIO1 pin
  digitalWrite(LED_BUILTIN, !state);     // set pin to the opposite state
  ++count;
  // 当翻转次数达到20次的时候,切换led的闪烁频率,每隔0.1s翻转一次
  if (count == 20) {
    flipper.attach(0.1, flip);
  }
  // 当次数达到120次的时候关闭ticker
  else if (count == 120) {
    flipper.detach();
  }
}
void setup() {
  //LED_BUILTIN 对应板载LED的IO口
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  //每隔0.3s 翻转一下led状态
  flipper.attach(0.3, flip);
}
void loop() {
}/**
*板载LED每隔25ms灭,每隔26ms亮
*/
#include <Ticker.h>
Ticker tickerSetHigh;
Ticker tickerSetLow;
void setPin(int state) {
  digitalWrite(LED_BUILTIN, state);
}
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  // 每隔25ms调用一次 setPin(0)
  tickerSetLow.attach_ms(25, setPin, 0);
  // 每隔26ms调用一次 setPin(1)
  tickerSetHigh.attach_ms(26, setPin, 1);
}
void loop() {
}

 
                     
                     
                        
                        