一、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() {
}