esp-idf使用教程

1、开发环境搭建(win10+vscode)

参考网络资料。

2、helloworld

使用esp-idf提供的模板工程快速构建一个项目(打开示例工程快捷键ctrl+Alt+P)。
在这里插入图片描述
设置串口芯片型号和编译以及烧录、串口监视命令
在这里插入图片描述

2、设置波特率

点击右下角“齿轮按钮”,搜索框输入urat,打开相关设置
在这里插入图片描述

3、gpio控制(点亮LED为例子)

操作思想:由于esp-idf缺少相关文档,所以我们怎么知道操作引脚函数需要的参数是什么呢,答案是F12查看函数原型,通过查看函数的原型去查找函数需要的参数,如果参数也是库定义的,那就F12到参数的定义去查看。如下以gpio_set_direction()引脚状态设置函数为例子演示:
通过查看如下函数原型我们可知道该函数需要两个参数。

esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
{
    GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);

    if ((GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) != true) && (mode & GPIO_MODE_DEF_OUTPUT)) {
        ESP_LOGE(GPIO_TAG, "io_num=%d can only be input", gpio_num);
        return ESP_ERR_INVALID_ARG;
    }

    esp_err_t ret = ESP_OK;

    if (mode & GPIO_MODE_DEF_INPUT) {
        gpio_input_enable(gpio_num);
    } else {
        gpio_input_disable(gpio_num);
    }

    if (mode & GPIO_MODE_DEF_OUTPUT) {
        gpio_output_enable(gpio_num);
    } else {
        gpio_output_disable(gpio_num);
    }

    if (mode & GPIO_MODE_DEF_OD) {
        gpio_od_enable(gpio_num);
    } else {
        gpio_od_disable(gpio_num);
    }

    return ret;
}

F12跳转到第一个参数的定义,发现是一个枚举类型的结构体,定义了芯片引脚。
在这里插入图片描述
F12跳转到第二个参数的定义,可知是管脚的状态。
在这里插入图片描述

1.引入gpio库文件
在这里插入图片描述
2.使用gpio_reset_pin()初始化引脚(2为例子)。

  gpio_reset_pin(2);    //初始化引脚

3.gpio_set_direction();

gpio_set_direction(2, GPIO_MODE_OUTPUT); // 设置管脚输出模式
  1. gpio_set_level();
 gpio_set_level(2, status);             // 设置管脚状态

5.LED灯间隔一秒闪烁代码

#include <stdio.h>
#include "esp_log.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

uint32_t status = 0;

void app_main(void)
{
  gpio_reset_pin(2);                       // 初始化引脚
  gpio_set_direction(2, GPIO_MODE_OUTPUT); // 设置管脚输出模式
  while (1)
  {
    status != status;                      // 取反
    gpio_set_level(2, status);             // 设置管脚状态
    vTaskDelay(1000 / portTICK_PERIOD_MS); // 延时1000/1秒运行周期=1
  }
}

如果闪烁时间不对注意查看如下配置
在这里插入图片描述

4、查看freertos中所有的进程信息

在这里插入图片描述

#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

int count = 0;
char prtTaskList[250];
void app_main(void)
{
  ESP_LOGI("COUNT", "Tick(ms):%d", portTICK_PERIOD_MS);

  // vTaskDelay(1000 / portTICK_PERIOD_MS); // 延时1秒
  printf("**************************************\n");
  printf("Task       state   prio     stack  Num\n");
  printf("**************************************\n");
  printf(prtTaskList);
  printf("**************************************\n");
}

5、自定义配置菜单

参考官方说明:乐鑫编程指南
新建一个配置文件,Kconfig.projbuild
在这里插入图片描述
打开menuconfig查看新增配置
在这里插入图片描述
设置
在这里插入图片描述
.c文件获取项目配置文件中的值。你可以在菜单中动态设置一个变量,该变量的声明会出现在项目配置文件中,复制变量名到源代码文件中即可引用菜单动态设置的变量。
在这里插入图片描述
在这里插入图片描述

6、向nvs中写入复杂数据(结构体数组以二进制的形式写入)

#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "esp_log.h"

void app_main()
{
  char *bilibili_namespace = "BILIBILI_abc";
  nvs_flash_init();

  nvs_handle_t bilibili_handle;
  nvs_open(bilibili_namespace, NVS_READWRITE, &bilibili_handle);

  // 创建一个结构体并用结构体创建结构体数组,存储两个无线网的账号密码
  uint32_t max_ap = 2;
  typedef struct
  {
    char ssid[50];
    char password[50];
  } ap_t;
  ap_t aps_set[max_ap];
  ap_t aps_get[max_ap];
  size_t length = sizeof(aps_get);

  for (int i = 0; i < max_ap; i++)
  {
    strcpy(aps_set[i].ssid, "bilibili");
    strcpy(aps_set[i].password, "123456");
  }

  // write
  nvs_set_blob(bilibili_handle, "aps", aps_set, sizeof(aps_set));
  // read
  nvs_get_blob(bilibili_handle, "aps", aps_get, &length);

  for (int i = 0; i < max_ap; i++)
  {
    ESP_LOGI("NVS", "ssid:password %s:%s", aps_get[i].ssid, aps_get[i].password);
  }

  // NVS
  nvs_commit(bilibili_handle);
  // 关闭NVS
  nvs_close(bilibili_handle);
  // 执行重启
  esp_restart();
}

7、 打印内存数据

#include <stdio.h>
#include <string.h>
#include "esp_system.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "esp_log.h"

void printMemory(unsigned char *address, int size)
{
  int count;
  for (count = 0; count < size; count++)
  {
    printf("%.2x", address[count]);
  }
  printf("\n");
}

void app_main()
{
  uint32_t num = 200;
  printMemory((unsigned char *)&num, 4);
  num = 100;
  printMemory((unsigned char *)&num, 4);

}

8、ESP32的WiFi模块

#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
void app_main(void)
{
  ESP_LOGI("WIFI", "0. 初始化NVS存储");
  esp_err_t ret = nvs_flash_init();
  if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
  {
    ESP_ERROR_CHECK(nvs_flash_erase());
    ret = nvs_flash_init();
  }
  ESP_ERROR_CHECK(ret);

  ESP_LOGI("WIFI", "1. Wi-Fi 初始化阶段");
  ESP_ERROR_CHECK(esp_netif_init());
  ESP_ERROR_CHECK(esp_event_loop_create_default());
  esp_netif_create_default_wifi_sta();

  wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT();
  ESP_ERROR_CHECK(esp_wifi_init(&wifi_config));

  ESP_LOGI("WIFI", "2. Wi-Fi 初始化阶段");
  ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

  ESP_LOGI("WIFI", "3. Wi-Fi 启动阶段");
  ESP_ERROR_CHECK(esp_wifi_start());

  ESP_LOGI("WIFI", "4. Wi-Fi 扫描");
  wifi_country_t wifi_country_config = {
      .cc = "CN",
      .schan = 1,
      .nchan = 13,
  };
  ESP_ERROR_CHECK(esp_wifi_set_country(&wifi_country_config));
  ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, true));

  uint16_t ap_num = 0;
  ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_num));
  ESP_LOGI("WIFI", "AP Count : %d", ap_num);

  uint16_t max_aps = 20;
  wifi_ap_record_t ap_records[max_aps];
  memset(ap_records, 0, sizeof(ap_records));

  uint16_t aps_count = max_aps;
  ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&aps_count, ap_records));

  ESP_LOGI("WIFI", "AP Count: %d", aps_count);

  printf("%30s %s %s %s\n", "SSID", "频道", "强度", "MAC地址");

  for (int i = 0; i < aps_count; i++)
  {
    printf("%30s  %3d  %3d  %02X-%02X-%02X-%02X-%02X-%02X\n", ap_records[i].ssid, ap_records[i].primary, ap_records[i].rssi, ap_records[i].bssid[0], ap_records[i].bssid[1], ap_records[i].bssid[2], ap_records[i].bssid[3], ap_records[i].bssid[4], ap_records[i].bssid[5]);
  }
}

9、esp32多任务扫描附近所有WiFi

#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_task_wdt.h"

// wifi_scan
void wifi_scan_task()
{

  ESP_LOGI("WIFI", "4. Wi-Fi 扫描");
  wifi_country_t wifi_country_config = {
      .cc = "CN",
      .schan = 1,
      .nchan = 13,
  };
  ESP_ERROR_CHECK(esp_wifi_set_country(&wifi_country_config));
  ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, false));

  uint16_t ap_num = 0;
  ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_num));
  ESP_LOGI("WIFI", "AP Count : %d", ap_num);

  vTaskDelete(NULL);
}

void wifi_scan_show()
{
  uint16_t ap_num = 0;
  ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_num));
  ESP_LOGI("WIFI", "AP Count : %d", ap_num);

  uint16_t max_aps = 20;
  wifi_ap_record_t ap_records[max_aps];
  memset(ap_records, 0, sizeof(ap_records));

  uint16_t aps_count = max_aps;
  ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&aps_count, ap_records));

  ESP_LOGI("WIFI", "AP Count: %d", aps_count);

  printf("%30s %s %s %s\n", "SSID", "频道", "强度", "MAC地址");

  for (int i = 0; i < aps_count; i++)
  {
    printf("%30s  %3d  %3d  %02X-%02X-%02X-%02X-%02X-%02X\n", ap_records[i].ssid, ap_records[i].primary, ap_records[i].rssi, ap_records[i].bssid[0], ap_records[i].bssid[1], ap_records[i].bssid[2], ap_records[i].bssid[3], ap_records[i].bssid[4], ap_records[i].bssid[5]);
  }
  vTaskDelete(NULL);
}

// 1. 定义事件处理程序
void run_on_event(void *handler_arg, esp_event_base_t base, int32_t id, void *event_data)
{
  // 事件处理程序逻辑
  ESP_LOGE("event_handle", "BASE:ID %s:%d", base, id);
  // WIFI_EVENT_SCAN_DONE,
  //     WIFI_EVENT_STA_START,
  switch (id)
  {
  case WIFI_EVENT_STA_START:
    ESP_LOGE("event_handle", "WIFI_EVENT_STA_START");
    // 创建任务wifi_scan任务
    xTaskCreate(wifi_scan_task, "wifi scan task", 1024 * 12, NULL, 1, NULL);
    break;
  case WIFI_EVENT_SCAN_DONE:
    ESP_LOGE("event_handle", "WIFI_EVENT_SCAN_DONE");
    // 创建任务wifi_scan任务
    xTaskCreate(wifi_scan_show, "wifi_scan_show", 1024 * 12, NULL, 1, NULL);
    break;
  default:
    break;
  }
}

void app_task(void *pt)
{

  ESP_LOGI("APP_TASK", "APP_TASK create success!");
  esp_event_handler_register(ESP_EVENT_ANY_BASE, ESP_EVENT_ANY_ID, run_on_event, NULL);
  while (1)
  {
    // ESP_LOGI("APP_TASK", "APP_TASK 无聊的运行中!");
    vTaskDelay(1000 / portTICK_PERIOD_MS); // 定时喂狗
  }
}

/*
task_list()
显示当前的所有FreeRTOS任务
使用前,请在menuconfig中启动
Enable FreeRTOS trace facility
Enable FreeRTOS stats formatting functions
*/
void task_list(void)
{
  char ptrTaskList[250];
  vTaskList(ptrTaskList);
  printf("*******************************************\n");
  printf("Task            State   Prio    Stack    Num\n");
  printf("*******************************************\n");
  printf(ptrTaskList);
  printf("*******************************************\n");
}

void app_main(void)
{
  ESP_LOGI("WIFI", "0. 初始化NVS存储");
  esp_err_t ret = nvs_flash_init();
  if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
  {
    ESP_ERROR_CHECK(nvs_flash_erase());
    ret = nvs_flash_init();
  }
  ESP_ERROR_CHECK(ret);

  ESP_LOGI("WIFI", "1. Wi-Fi 初始化阶段");
  ESP_ERROR_CHECK(esp_netif_init());
  ESP_ERROR_CHECK(esp_event_loop_create_default());
  esp_netif_create_default_wifi_sta();

  wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT();
  ESP_ERROR_CHECK(esp_wifi_init(&wifi_config));

  // 创建任务
  xTaskCreate(app_task, "APP TASK", 1024 * 12, NULL, 1, NULL);

  ESP_LOGI("WIFI", "2. Wi-Fi 初始化阶段");
  ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

  ESP_LOGI("WIFI", "3. Wi-Fi 启动阶段");
  ESP_ERROR_CHECK(esp_wifi_start());

  while (1)
  {
    // ESP_LOGI("main_task", "main_task 无聊的运行中!");
    vTaskDelay(1000 / portTICK_PERIOD_MS); // 定时喂狗
  }
  vTaskDelete(NULL); // 删除当前任务
}
  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值