ESP32-NVS保存

ESP32-NVS保存

1. 简介

1.NVS是什么?

  • NVS = Non-Volatile Storage(非易失性储存)
  • 掉电不丢失,专门存键值对(key-value),比如配置,参数,计数,WIFI密码等
  • 比之间写Flash安全,简单。
  • 支持类型:intstringblob(二进制数据:结构体,数组)

2. 常用函数

1.必要添加的头文件

c 复制代码
#include "nvs_flash.h"
#include "nvs.h"

2.初始化NVS

整个程序只需要执行一次

必须在使用NVS前使用,通常放到app_main()最开头

c 复制代码
//初始化 NVS 闪存
esp_err_t err = nvs_flash_init();
if(err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
	//如果NVS分区满了/版本不匹配,先擦除再初始化
	ESP_ERROR_SHECK(nvs_flash_erase());
	err == nvs_flash_init();
}
ESP_ERROR_CHECK(err); //检测是否初始化成功

3.打开NVS句柄

在读写数据前必须先打开一个NVS命名空间(namespace)

c 复制代码
nvs_open(const char* namespace_name, nvs_open_mode_t open_mode, nvs_handle_t *out_handle)

参数

  • namespace_name:命名空间,名字顺便起。
  • open_mode :打开方式,
    • NVS_READWRITE:读写
    • NVS_READONLY:只读
  • out_handle:句柄

例如

c 复制代码
nvs_hanle_t my_handle;

//打开命名空间"storage",读写模式
err = nvs_open("storage",NVS_READWRITE,&my_handle);
if(err != ESP_OK){
	printf("打开NVS失败!(%s)\n",esp_err_to_name(err));
	return ;
}

4.写入数据

1.整型数据

将值写入到键中,并保存在MVS里面

c 复制代码
esp_err_t nvs_set_x(nvs_handle_t handle, const x* key, int8_t value);
  • nvs_set_x:中的x为值的数据类型,如:i8,u8,str,blob等
  • handle: 句柄
  • key :键
  • value:值

int8_t

c 复制代码
esp_err_t nvs_set_i8 (nvs_handle_t handle, const char* key, int8_t value);

uint8_t

c 复制代码
esp_err_t nvs_set_u8 (nvs_handle_t handle, const char* key, int8_t value);

int16_t

c 复制代码
esp_err_t nvs_set_i16 (nvs_handle_t handle, const char* key, int8_t value);

uint16_t

c 复制代码
esp_err_t nvs_set_u16 (nvs_handle_t handle, const char* key, int8_t value);

int32_t

c 复制代码
esp_err_t nvs_set_i32 (nvs_handle_t handle, const char* key, int8_t value);

uint32_t

c 复制代码
esp_err_t nvs_set_u32 (nvs_handle_t handle, const char* key, int8_t value);

int64_t

c 复制代码
esp_err_t nvs_set_i64 (nvs_handle_t handle, const char* key, int8_t value);

uint64_t

c 复制代码
esp_err_t nvs_set_u64 (nvs_handle_t handle, const char* key, int8_t value);

例子

c 复制代码
static void nvs_save_dat(const char *dat, const u8 num)
{
    nvs_handle_t nvs_handle;
    // 参数 :地址空间  打开方式 句柄
    nvs_open("dat_cfg", NVS_READWRITE, &nvs_handle); //打开句柄
    //参数 :句柄 键 值
    nvs_set_u8(nvs_handle, "dat", num); //填入数据
    nvs_commit(nvs_handle); //提交数据
    nvs_close(nvs_handle); //关闭句柄
}

2.字符串数据

c 复制代码
esp_err_t nvs_set_str (nvs_handle_t handle, const char* key, const char* value);

例子

c 复制代码
static void nvs_save_wifi(const char *ssid, const char *pwd)
{
    nvs_handle_t nvs_handle;
    nvs_open("wifi_cfg", NVS_READWRITE, &nvs_handle);
    nvs_set_str(nvs_handle, "ssid", ssid);
    nvs_set_str(nvs_handle, "pwd", pwd);
    nvs_commit(nvs_handle);
    nvs_close(nvs_handle);
}

3. 二进制数据

包括:结构体,数组

c 复制代码
esp_err_t nvs_set_blob(nvs_handle_t handle, const char* key, const void* value, size_t length);

例子

c 复制代码
// 定义一个结构体
typedef struct {
    int temperature;
    float humidity;
} config_t;

config_t cfg = {25, 60.5};

// 写入 blob(二进制对象)
err = nvs_set_blob(my_handle, "config", &cfg, sizeof(config_t));
ESP_ERROR_CHECK(err);

5.提交数据

使用NVS_SET_x()函数写入数据后,需要使用nvs_commit()进行提交,不然数据没法真正保存。

c 复制代码
esp_err_t nvs_commit(nvs_handle_t handle);

参数

  • handle :句柄

例子

c 复制代码
static void nvs_save_wifi(const char *ssid, const char *pwd)
{
    nvs_handle_t nvs_handle;
    nvs_open("wifi_cfg", NVS_READWRITE, &nvs_handle);  //打开句柄
    nvs_set_str(nvs_handle, "ssid", ssid);  //写入数据
    nvs_set_str(nvs_handle, "pwd", pwd);
    nvs_commit(nvs_handle); //提交数据
    nvs_close(nvs_handle); //关闭句柄
}

6.获取数据

从键中获取对应的值

1.获取整型数据

与写入数据对应将set``改为get`即可。

c 复制代码
esp_err_t nvs_get_i8 (nvs_handle_t handle, const char* key, int8_t* out_value);

参数

  • handle :句柄
  • key : 键
  • out_value: 值(参数是指针类型的,要使用地址进行接收)

2.获取字符串数据

c 复制代码
esp_err_t nvs_get_str (nvs_handle_t handle, const char* key, char* out_value, size_t* length);

参数:

  • handle:句柄
  • key: 键
  • out_value·:值
  • length:要获取字符串的长度
    例如
c 复制代码
static void nvs_read_wifi(void)
{
    nvs_handle_t nvs_handle;
    if(nvs_open("wifi_cfg", NVS_READONLY, &nvs_handle) == ESP_OK){
        size_t len = sizeof(g_sta_ssid);
        nvs_get_str(nvs_handle, "ssid", g_sta_ssid, &len);
        len = sizeof(g_sta_pass);
        nvs_get_str(nvs_handle, "pwd", g_sta_pass, &len);
        nvs_close(nvs_handle);
    }
}

3.获取二进制数据

c 复制代码
esp_err_t nvs_get_blob(nvs_handle_t handle, const char* key, void* out_value, size_t* length);

参数:

  • handle:句柄
  • key: 键
  • out_value·:值
  • length:要获取字符串的长度

7.删除

1.删除键

从内存在将该键进行删除。(包括对应的值)

c 复制代码
esp_err_t nvs_erase_key(nvs_handle_t handle, const char* key);

2.删除命名空间里所有的键

c 复制代码
esp_err_t nvs_erase_all(nvs_handle_t handle);

8.关闭句柄

c 复制代码
void nvs_close(nvs_handle_t handle);

3.wifi储存例子

c 复制代码
char g_sta_ssid[32] = {0}; //要连接的wifi名称
char g_sta_pass[64] = {0}; //保存家里WIFI密码

//==================== NVS 存储 ====================
//读取闪存分区里的WIFI账号和密码
static void nvs_read_wifi(void)
{
    nvs_handle_t nvs_handle;
    if(nvs_open("wifi_cfg", NVS_READONLY, &nvs_handle) == ESP_OK){
        size_t len = sizeof(g_sta_ssid);
        nvs_get_str(nvs_handle, "ssid", g_sta_ssid, &len);
        len = sizeof(g_sta_pass);
        nvs_get_str(nvs_handle, "pwd", g_sta_pass, &len);
        nvs_close(nvs_handle);
    }
}
//把WIFI名称和密码写进闪存分区里
static void nvs_save_wifi(const char *ssid, const char *pwd)
{
    nvs_handle_t nvs_handle;
    nvs_open("wifi_cfg", NVS_READWRITE, &nvs_handle);
    nvs_set_str(nvs_handle, "ssid", ssid);
    nvs_set_str(nvs_handle, "pwd", pwd);
    nvs_commit(nvs_handle);
    nvs_close(nvs_handle);
}
//清除闪存里面的WIFI数据
static void nvs_clear_wifi(void)
{
    nvs_handle_t nvs_handle;
    nvs_open("wifi_cfg", NVS_READWRITE, &nvs_handle);
    nvs_erase_all(nvs_handle);
    nvs_commit(nvs_handle);
    nvs_close(nvs_handle);
    ESP_LOGI(TAG, "✅ 已重置配网,重启生效");
    esp_restart();
}

void app_main()
{
	esp_err_t err = nvs_flash_init();
	if(err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
		//如果NVS分区满了/版本不匹配,先擦除再初始化
		ESP_ERROR_SHECK(nvs_flash_erase());
		err == nvs_flash_init();
	}
	ESP_ERROR_CHECK(err); //检测是否初始化成功
	
  nvs_read_wifi(); //读取是否存有WIFI信息
  if(strlen(g_sta_ssid) > 0) {  //直接连接
     start_sta_wifi(g_sta_ssid, g_sta_pass);
  } else {    //配网
     start_ap_web_server();
  }

}
相关推荐
AOI小白新手上路21 小时前
江科协51单片机 17-2 红外遥控电机调速实验调试总结
单片机·嵌入式硬件·51单片机
oshan20121 天前
零基础STM32入门教程--10-PWM 呼吸灯
stm32·单片机·嵌入式硬件
jianqiang.xue1 天前
智能体整体架构设计:四大模块与目录组织
单片机·嵌入式硬件·物联网·架构·esp32
Messy create1 天前
【BMS-AFE-温度检测】
stm32·单片机·能源
东莞市永盛电气1 天前
三相208V变380V变压器,出海工业设备供电适配方案
python·单片机·嵌入式硬件
新晨单片机设计1 天前
S001A-基于STM32单片机超声波视力保护仪【Proteus仿真+Keil程序+原理图】
stm32·单片机·proteus
星河单片机1 天前
STM32驱动Y01-3IN1空气质量模块+OLED显示完整教程
stm32·单片机·嵌入式硬件·空气质量·甲醛检测·二氧化碳检测·tvoc检测
别催小唐敲代码1 天前
stm32_mpu6050_滤波教程
stm32·单片机·嵌入式硬件
CPETW1 天前
USB TO I2C_(Excel)_Scan ---- 1000KHz总线速率测试_A
c语言·开发语言·网络·科技·单片机
单片机仿真设计1 天前
【proteus仿真】基于 51 单片机距离传感器警报装置设计(仿真图+程序)
单片机·嵌入式硬件·51单片机·proteus·毕设