目录一、ESP - IDF版本1、先来看各个版本所支持的芯片区分二、安装VSCODE1、网址2、安装过程3、配置下中文三、安装IDF插件1、搜索安装2、安装好好后如下图4、配置 开发环境以及在线安装ESP-IDF版本四、项目新建1、DEMO工程拖进VSCODE打开2、底部菜单栏信息3、烧录程序安装工具根本原因五、工程新建六、工程架构定义理解1、下图是官方提供的基本架构定义2、开始构建3、打开工程4、构建工程七、工程添加第三方组件1、乐鑫组件注册表2、选型3、选择想要的组件八、如何调试九、时钟树十、引脚配置十一、中断优先级十二、串口开发1、UART硬件控制流阈值为什么不启用流控还要填预防万一系统可能检查2、时钟源怎么选择3、流控引脚选择4、串口队列5、串口中断实际驱动的工作方式十三、系统定时器十四、通用定时器1、通用定时器时钟源选择2、定时器中断回调选择3、nvs_flash_init十五、LEDC​编辑1、PWM引脚复用2、PWM通道3、PWM底层计数机制编程你不用管 hpoint/lpoint十六、硬件IIC1、XL9535 IIC的使用2、AT24C022、ESP32S3引脚复用3、IIC通讯执行策略i2c_master_cmd_begin十七、硬件SPI1、数据传输过程2、SPI的4种通讯模式3、SPI的各路区别4、SPI支持的特性5、应用SPI显示屏彩屏的驱动十八、WIFI1、模式2、AP启动过程3、STA模式4、WIFI扫描热点工程5、WIFI路由实验一、ESP - IDF版本1、先来看各个版本所支持的芯片区分二、安装VSCODE1、网址VSCODE下载网址2、安装过程3、配置下中文点击重启汉化完成如下图三、安装IDF插件1、搜索安装2、安装好好后如下图4、配置 开发环境以及在线安装ESP-IDF版本1点击侧边栏ESP-IDF资源管理器之后点击“打开ESP-IDF安装管理”2选择第一个“start Easy Inatal”3选择版本安装然后中间打勾起来把C盘选择到其他盘我是选择待D盘避免占用C盘空间这里我选择V5.4.4然后回进入安装版本以及python环境变量配置这个时间估计10几分钟静静等待安装完成即可。4安装完成如下图我点击橙色的按钮‘delete’删除安装包避免站空间。在点击红色按钮“Go to Dashboard”5点击“Open IDF terminal”运行结果到此我们python环境和IDF开发版本安装完成。值得注意的我们从github下载别人代码它可能是其他IDF版本开发不一定都是5.4版本开发所以根据编译提示我们在自己安装对应版本即可对下载下来的程序进行开发。四、项目新建1、DEMO工程拖进VSCODE打开选择信任2、底部菜单栏信息可以看到当亲安装的IDF版本信息以及选择下载端口和选择芯片型号3、烧录程序ESP32-S3 芯片内部集成了 USB Serial/JTAG 控制器直接通过USB OTG 接口GPIO19 D-、GPIO20 D即可实现 JTAG 调试和下载。串口烧录比较简单这里我们说下Jtag烧录我遇到不少问题。Can’t perform JTAG flash, because OpenOCD server is not running!❌ Error: libusb_open() failed with LIBUSB_ERROR_NOT_FOUND1先把设备管理器打开我们修改USB端口接上Jtag显示如下解决办法安装工具下载zadigzadig2修改驱动加载所有驱动安装驱动1等待安装完成。安装驱动2安装驱动3修噶成后再次查看设备管理器显示如下图即完成4、VSCODE Jtag烧录现象在VSCODE点击烧录时候显示如下图意思是 OpenOCD 找不到FTDI 芯片的 JTAG 调试器如 ESP-Prog、FT2232H 等。所以每当我要烧录时候都必须打开Power shell运行这条指令后就可以Jtag烧录openocd -f board/esp32s3-builtin.cfg也就是每次打开VSCODE我需要先运行这个条指令才能Jtag烧录这样才能烧录成功。后面我才发现根本原因VS Code ESP-IDF 扩展的OpenOCD 配置文件没有设置为esp32s3-builtin.cfg而是用了默认的 FTDI 配置。验证下载这次成功了五、工程新建QIO速度最快配置FREERTOS,为什么要用它呢我们要用他的延迟函数VSDELAYtsak分区表配置设置为“自定义分区”然后修改名字partitions-16MiB.csv名字要写对后面再讲解最后点击保存保存后左边栏多了一个sdk配置而old是老的配置旧的配置我们可以删除掉右击删除接下来编辑分区表ctrlshiftp 输入分区点击新增保存然后点击下面进行构建项目构建需要5分钟左右比较慢成功如下六、工程架构定义理解1、下图是官方提供的基本架构定义优化优化下2、开始构建1复制裸机工程2新建文件夹3、打开工程由于我们新增了一个CMakeLists.txt所以需要修改底下的CMakeLists.txt的内容新增两条语句第一句是添加新增的组件目录第二句是执行编译有错会报错进来BSP的CMakeLists.txt需要定义源文件路径声明源文件和头文件driver是后面要用的 现在添加进来再添加两条语句ESP_IDFCMake用到的宏主要用来注册组件第二个是为当前添加编译选项后续这两个不需要改保持就好。4、构建工程注意踩坑1、分区表名字写错会导致构建失败2、子目录LED在LED文件夹里面如果漏掉LED文件夹也会导致构建失败这两个错误是我操作时候犯的错误错误如下图提示失败成功如下图到这里这个DEMO既可以作为我们开发的模版了。七、工程添加第三方组件1、乐鑫组件注册表2、选型3、选择想要的组件安装成功显示如下可以命令安装在终端输入对应 的组件命令即可在终端输入 粘贴命令即可重新构建成功一定要先删除在构建不删除之前的胡构建失败如果提示删除失败可以手动右击build文件夹给他删除构建成功后左边菜单栏会显示如果我们自定义的额组件LED要用第三方组件要到CMake..这个去声明如果在main使用则不需要声明。八、如何调试1、连接Jtag进入调试模式点击任意一个2、烧录进入代码选择这四个按键调试变量添加监视器终端调试控制| 按键 | 功能 || ------------------------ | ---------- || Ctrl ] | 退出 Monitor || Ctrl T 然后 Ctrl H | 显示所有快捷键帮助 || Ctrl T 然后 Ctrl R | 复位 ESP32 || Ctrl T 然后 Ctrl F | 切换流控 |九、时钟树十、引脚配置取决于使用选型如果你选择是裸芯片就需要外置存储芯片比如红框的浙西芯片不内置PSRAM,左边是模块型号中间是芯片型号有些直接买模块模块里面已经外接好flash芯片如果你买芯片那你一定需要电路图在外接一个flash芯片PSRAM就看你选型的芯片内置的就不要外接。十一、中断优先级ESP32数值越大优先级越高注意NMI这个是最大的可以抢占任意一个中断配置中断注意事项1、gpio_install_isr_service(ESP_INTR_FLAG_LEVEL3)里的ESP_INTR_FLAG_LEVEL3表示的是CPU 中断优先级Priority Level 3它告诉 ESP-IDF 的中断分配器帮我申请一个优先级为 3 级的 CPU 中断向量而不是我要中断号 3。2、ESP32-S3 的所有 GPIO 引脚共享同一个或少数几个底层中断源// 示例把 GPIO 中断整体设为优先级 3 gpio_install_isr_service(ESP_INTR_FLAG_LEVEL3);一旦安装完成所有 GPIO 引脚的外部中断都是这个优先级你无法让 GPIO5 是高优先级、GPIO6 是低优先级。3、ESP_INTR_FLAG_LEVEL3是在向系统提要求——给我分配一个优先级为 3的中断通道至于具体用到 CPU 32 个中断向量中的哪一个中断号 0~31由 ESP-IDF 的中断矩阵Interrupt Matrix自动分配你不用管。4、gpio_install_isr_service(0)默认由系统自动选择中断优先级和 CPU 核心十二、串口开发注意串口配置1、UART硬件控制流阈值UART 硬件接收 FIFO 深度是 128 字节。当接收 FIFO 里的数据达到 122 字节时RTS 引脚会拉高告诉对方别发了我要满了这 6 个字节是安全余量guard band。因为 RTS 信号传到对方、对方再停止发送中间会有延迟线路延迟 对方处理延迟。预留 6 个字节的缓冲防止在这短暂延迟内 FIFO 被撑爆。uart_config.rx_flow_ctrl_thresh 122;/* 硬件控制流阈值,预留6字节安全冗余量硬件的FIFO 128字节时的标准余量, 当接收 FIFO 里的数据达到 122字节时RTS 引脚自动拉高→ 告诉对方我快满了暂停发送*/为什么不启用流控还要填预防万一系统可能检查2、时钟源怎么选择普通通信 →UART_SCLK_APB现在的选择是对的要睡眠省电且 UART 不能断 → 换成UART_SCLK_XTAL别选 RTC32kHz 频率太低基本没法正常通信3、流控引脚选择uart_set_pin(USART_UX, USART_TX_GPIO_PIN, USART_RX_GPIO_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);/* _NO_CHANGERTS 和 CTS 这两个引脚我不关心不要给我分配 GPIO这样驱动就不会去占额外的 GPIO代码也更简洁。*/4、串口队列uart_driver_install(USART_UX, RX_BUF_SIZE * 2, RX_BUF_SIZE * 2, 20, NULL, 0);uart_driver_install( USART_UX, // 第1个UART 端口号UART_NUM_0 / 1 / 2 RX_BUF_SIZE * 2, // 第2个RX 接收环形缓冲区大小字节 RX_BUF_SIZE * 2, // 第3个TX 发送环形缓冲区大小字节 20, // 第4个事件队列长度最多缓存20个事件 NULL, // 第5个事件队列句柄NULL 不创建队列 0 // 第6个中断分配标志0 默认配置 );这句代码意思是给USART_UX串口安装驱动分配RX/TX 各两倍缓冲空间预留20 个事件槽位不启用事件队列中断用默认配置。TX 发送环形缓冲区大小大于0就可以异步发送数据先存缓冲中断自动发送等于0就禁用 TX 缓冲uart_write_bytes阻塞直到所有数据写入硬件 FIFO5、串口中断1怎么产生中断STM32Z这类是接收一个字节产生中断的。ESP32有一个中断触发阈值此中断阈值不是前面的硬件流控阈值默认是120字节即硬件的FIFO会接收到120字节才会产生中断修改120字节代码默认如此你可以不需要写这两句代码// ✅ 修改 RX FIFO 满阈值默认 120 uart_set_rx_full_threshold(UART_NUM_0, 120); // 设为 1收到 120 字节就中断 // ✅ 修改 RX 超时阈值默认 10 uart_set_rx_timeout(UART_NUM_0, 10); // 10 个字符时间实际驱动的工作方式ESP-IDF 默认采用阈值中断 超时中断双保险硬件接收120字节120字节一道产生中断把120字节搬运给你软件开启的缓存里面好处就是不会频繁产生中断如果1字节产生中断不然CPU 会被频繁打断设置函数默认120字节无需设置除非你要修改// 默认通常是 120 字节触发一次中断uart_set_rx_full_threshold(UART_NUM_1, 120);// 同时配一个超时FIFO 里有数据但 10 个字符时间内没新数据也触发中断uart_set_rx_timeout(UART_NUM_1, 10);2串口服务函数在哪有但不是你自己写中断函数而是 ESP-IDF 驱动层帮你封装好了。你只需要做读取就可以不用编写服务函数经典写法QueueHandle_t uart_queue;uart_driver_install(UART_NUM_1, 1024, 1024, 20, uart_queue, 0);// 创建一个任务监听事件void uart_event_task(void *pvParameters) {uart_event_t event;while (1) {if (xQueueReceive(uart_queue, event, portMAX_DELAY)) {switch (event.type) {case UART_DATA:// 有数据到达去读uart_read_bytes(UART_NUM_1, buf, event.size, portMAX_DELAY);break;case UART_FIFO_OVF:// FIFO 溢出数据丢了break;case UART_FRAME_ERR:// 帧错误break;}}}}注意:我们只管读取不用管读取写入的指针偏移量系统封装好了十三、系统定时器esp_timer在 ESP32-S3 上底层绑定的是SYSTIMER系统定时器这个硬件模块。根据芯片手册SYSTIMER 的时钟源硬连线到 XTAL_CLK40 MHz没有时钟选择开关。为了低功耗兼容性当 ESP32-S3 进入 Light-sleep 时APB 总线时钟会停振或降频但 XTAL 晶振保持工作。1、添加esp_timer组件不添加程序会报错esptime.h里引用了#include esp_timer.h但esp_timer是 ESP-IDF 的一个独立内置组件它的头文件放在esp-idf/components/esp_timer/include/下。你写的ESPTIME是一个自定义组件在components/BSP/ESPTIME里ESP-IDF 的编译系统不会自动把其他组件的头文件路径暴露给它。你必须显式声明依赖关系。解决方法找到你的 ESPTIME 组件目录下的 CMakeLists.txt改成这样加上 REQUIRES esp_timervoid esptimer_int_init(uint64_t tps){esp_timer_handle_t esp_tim_handle; /* 定义定时器句柄 *//* 定义一个定时器结构体设置定时器配置参数 */esp_timer_create_args_t timer_arg {.callback esptimer_callback, /* 计时时间到达时执行的回调函数 */.arg NULL, /* 传递给回调函数的参数 */.dispatch_method ESP_TIMER_TASK, /* 进入回调方式,从定时器任务进入技术上可以省略因为 C 语言结构体初始化中未显式赋值的成员会自动置 0。而 ESP_TIMER_TASK 在枚举里通常就是 0。 */.name Timer, /* 定时器名称,可以省略不写*/};ESP_ERROR_CHECK(esp_timer_create(timer_arg, esp_tim_handle)); /* 创建定时器 */ESP_ERROR_CHECK(esp_timer_start_periodic(esp_tim_handle, tps)); /* 启动周期性定时器,tps设置定时器周期(us单位) *//*esp_err_t err esp_timer_create(timer_arg, esp_tim_handle);if (err ! ESP_OK) {ESP_LOGE(TAG, Error: %s, esp_err_to_name(err));abort(); // 重启}ESP_ERROR_CHECK返回 ESP_OK0→ 正常通过继续执行 */}十四、通用定时器1、通用定时器时钟源选择代码所对应的关系2、定时器中断回调选择#if SELECT_CALLBACK 0/*** brief 定时器组回调函数不常用* param args: 传入参数* retval 默认返回1*/void not_timer_group_isr_callback(void *args){timg_config_t *user_data (timg_config_t *) args;/* 获取定时器分组0中的哪个定时器产生中断*/uint32_t timer_intr timer_group_get_intr_status_in_isr(user_data-timer_group);/* 获取中断状态 */if (timer_intr TIMER_INTR_T0){/* 清除中断状态 */timer_group_clr_intr_status_in_isr(user_data-timer_group,user_data-timer_idx);/* 用户实现代码 *//* 存储当前计数值变量清零 */user_data-timer_count_value 0;/* 获取当前计数值 */user_data-timer_count_value timer_group_get_counter_value_in_isr(user_data-timer_group, user_data-timer_idx);/* 如果没有开启重装载那么想要周期警报必须设置警报值为t0 t0 */if (!user_data-auto_reload){user_data-alarm_value user_data-timing_time;/* 设置警报值ISR类型函数 */timer_group_set_alarm_value_in_isr(user_data-timer_group, user_data-timer_idx, user_data-alarm_value);}/* 重新使能定时器中断 */timer_group_enable_alarm_in_isr(user_data-timer_group, user_data-timer_idx);}else if (timer_intr TIMER_INTR_T1){/* 定时器1中断 */}else if (timer_intr TIMER_INTR_WDT){/* 看门狗定时器中断 */}else{}}#else/*** brief 定时器组回调函数常用* param args: 传入参数* retval 默认返回1*/static bool IRAM_ATTR timer_group_isr_callback(void *args){timg_config_t *user_data (timg_config_t *) args;/* 存储当前计数值变量清零 */user_data-timer_count_value 0;/* 获取当前计数值 */user_data-timer_count_value timer_group_get_counter_value_in_isr(user_data-timer_group, user_data-timer_idx);LED0_TOGGLE();/* 如果没有开启重装载那么想要周期警报必须设置警报值为t0 t0 */if (!user_data-auto_reload){user_data-alarm_value user_data-timing_time;///* 设置警报值ISR类型函数 */timer_group_set_alarm_value_in_isr(user_data-timer_group, user_data-timer_idx, user_data-alarm_value);}return 1;}#endif不常用 旧版裸机式写法手动分发中断源、手动清标志、无 IRAM 保护、返回 void。常用 新版驱动推荐写法驱动自动管理中断上下文只写业务逻辑有 IRAM 保护返回 bool 支持任务切换。3、nvs_flash_initret nvs_flash_init(); /* 初始化NVS */if (ret ESP_ERR_NVS_NO_FREE_PAGES || ret ESP_ERR_NVS_NEW_VERSION_FOUND){ESP_ERROR_CHECK(nvs_flash_erase());ESP_ERROR_CHECK(nvs_flash_init());}/*初始化 NVSNon-Volatile Storage非易失性存储。ESP32-S3 的 Wi-Fi、蓝牙校准数据需要存在 Flash 的 NVS 分区里。即使你的程序不用 Wi-Fi很多例程也保留这行是模板代码。处理异常ESP_ERR_NVS_NO_FREE_PAGESNVS 分区写满了需要擦除重来ESP_ERR_NVS_NEW_VERSION_FOUNDNVS 格式版本不匹配比如你换了新 SDK擦除整个 NVS 分区再重新初始化。这会清空之前保存的 Wi-Fi 密码等数据。*/十五、LEDC1、PWM引脚复用可以任意引脚复用PWM除了链接flash的那些特殊引脚2、PWM通道每个 PWM 通道PWM0~PWM7都可以自由选择绑定到任意一个定时器Timer0~Timer3而不是固定配对。3、PWM底层计数机制编程你不用管 hpoint/lpointESP-IDF 的ledc驱动已经把这些底层寄存器封装好了。你写代码只需要关心两件事频率Hz占空比duty驱动会自动帮你算出 hpoint 和 lpoint 的差值。初始值要低电平就把占空比写0要高电平就把占空比写100hpoint 的作用是相位偏移错开多路 PWM 的开关时间降低电源纹波。日常调光、调速、调蜂鸣器音量hpoint 保持 0 就行只动 duty。不要被hpoint 带偏十六、硬件IIC1、XL9535 IIC的使用2、AT24C022、ESP32S3引脚复用ESP32-S3 内置2 个独立的 I2C 控制器I2C0 和 I2C1ESP32的硬件IIC引脚可以通过软件选择服用到任意一个引脚。前提| **内部 Flash/PSRAM** | GPIO 26 ~ 32 | 通常连接片外 SPI Flash 或 PSRAM复用会导致系统崩溃或不稳定 || **Strapping 引脚** | GPIO 0, GPIO 3, GPIO 45, GPIO 46 | 上电时决定芯片启动模式不建议复用做普通 I/O| **输入-only** | GPIO 37 ~ 42 | 部分封装下这些引脚只能做输入而 I2C 的 SCL 需要输出时钟| **USB 串口** | GPIO 19, GPIO 20 | 默认用于 USB-JTAG/Serial除非禁用 USB 功能3、IIC通讯执行策略i2c_master_cmd_begin在 ESP-IDF 的 I2C 主机 API 中通信不是直接读写而是分两步构建命令准备阶段用i2c_master_start()、i2c_master_write()、i2c_master_read()、i2c_master_stop()等函数把一次完整的 I2C 通信起始位 → 发地址 → 读/写数据 → 停止位组装成一个命令链表。执行命令发送阶段调用i2c_master_cmd_begin()把这个命令链表真正推到 I2C 总线上执行。esp_err_t i2c_master_cmd_begin(i2c_port_t i2c_num,i2c_cmd_handle_t cmd_handle,TickType_t ticks_to_wait);ret i2c_master_cmd_begin(self-port, cmd, 100 * (1 data_len) / portTICK_PERIOD_MS);详解ticks_to_wait最多等多久超时就报错简单说前面只是在写剧本这个函数才是上台表演。i2c_cmd_link_delete(cmd)释放命令链接使用的资源用完之后必须手动释放否则会造成内存泄漏。十七、硬件SPIMOSI:代表是主机输出 从机接收MOSO:主机输入从机输出1、数据传输过程SPI数据传输本质在第一个时钟周期记性数据移出。在第二个时钟周期进行数据移入。2、SPI的4种通讯模式模式0比较特殊在CS拉低开启起始信号时候它就已经移出数据 之后在第一个时钟周期移入数据。第二个时钟周期移出数据依次类推模式1在第一个时钟周期寄存器移出数据。第二个是时钟周期移入数据一次类推模式2在CS拉低开启起始信号时候它就已经移入数据 时钟默认是高电平之后在第一个时钟周期移入数据。第二个时钟周期移出数据依次类推模式3时钟默认是高电平在第一个时钟周期寄存器移出数据。第二个是时钟周期移入数据一次类推移入的时钟周期时候代表采样当前电平的最佳时段。常用是模式0和模式33、SPI的各路区别ESP32S3有4路SPISPI0-SPI3但是用户使用正常使用SPI2和SPI3原因如下4、SPI支持的特性数据传输越快数据线越多在一个时钟周期多个数据线并行传输自燃带宽就高。CS线指的是SPI2可以接6个从机设备。SPI3可以接3个从机设备5、应用SPI显示屏彩屏的驱动1彩屏与单片机引脚连接这里需要注意的是彩屏只需要接收数据不需要回传数据给 ESP32所以MOSI必须有发数据给屏幕MISO 不需要屏幕不回数据这个LCD_WR不是MISO,LCD_WR接到DC脚上2控制时序十八、WIFI1、模式2、AP启动过程3、STA模式4、WIFI扫描热点工程值得注意的函数esp_wifi_scan_start(NULL, true); /* 开始扫描附近的WIFI */config NULL表示使用默认参数扫描wifi_scan_config_t default_config {.ssid NULL, // 扫描所有 SSID不做过滤.bssid NULL, // 扫描所有 BSSID不做过滤.channel 0, // 扫描所有信道 (1-14 for 2.4GHz).show_hidden 0, // 不显示隐藏 SSID 的 AP.scan_type WIFI_SCAN_TYPE_ACTIVE, // 主动扫描发送 Probe Request.scan_time.active {.min 100, // 每个信道最短停留 100ms.max 300 // 每个信道最长停留 300ms}};block true阻塞模式阻塞模式 (true)函数会等待整个扫描过程完成遍历所有信道、收集 AP 信息后才返回。期间当前任务会被挂起。非阻塞模式 (false)函数立即返回扫描在后台进行。需要通过事件WIFI_EVENT_SCAN_DONE来获知扫描完成。ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(number, ap_info));/*number定义为12只能存储12个wifi热点如果超出系统把信号最好的12个保存其他丢弃*/print_auth_mode(ap_info[i].authmode);/*判断当前扫描到这个wifi热点是属于哪种认证模式*/在 ESP32-S3 的 Wi-Fi 扫描结果中authmode认证模式是wifi_ap_record_t结构体中的一个重要字段表示该 AP 使用的安全认证方式。// 位于 esp_wifi_types.htypedef enum {WIFI_AUTH_OPEN 0, // 开放网络无密码WIFI_AUTH_WEP, // WEP已淘汰不安全WIFI_AUTH_WPA_PSK, // WPA-Personal (PSK)WIFI_AUTH_WPA2_PSK, // WPA2-Personal (PSK) — 最常见WIFI_AUTH_WPA_WPA2_PSK, // 同时支持 WPA 和 WPA2WIFI_AUTH_WPA3_PSK, // WPA3-Personal (SAE)WIFI_AUTH_WPA2_WPA3_PSK, // 同时支持 WPA2 和 WPA3WIFI_AUTH_WAPI_PSK, // WAPI中国标准WIFI_AUTH_OWE, // Opportunistic Wireless Encryption (WPA3过渡)WIFI_AUTH_WPA3_ENT_192, // WPA3-Enterprise 192-bitWIFI_AUTH_WPA3_EXT_PSK, // WPA3-External PSKWIFI_AUTH_WPA3_EXT_PSK_MIXED_MODE, // WPA3-External PSK 混合模式WIFI_AUTH_MAX} wifi_auth_mode_t;print_cipher_type(ap_info[i].pairwise_cipher, ap_info[i].group_cipher);pairwise_cipher又名成对密钥加密算法表示 AP 用于保护单播数据帧的加密算法// 位于 esp_wifi_types.htypedef enum {WIFI_CIPHER_TYPE_NONE 0, // 无加密开放网络WIFI_CIPHER_TYPE_WEP40, // WEP 40-bitWIFI_CIPHER_TYPE_WEP104, // WEP 104-bitWIFI_CIPHER_TYPE_TKIP, // TKIPTemporal Key Integrity ProtocolWIFI_CIPHER_TYPE_CCMP, // CCMP/AESAES-CCMP目前最常用WIFI_CIPHER_TYPE_TKIP_CCMP, // TKIP CCMP 同时支持兼容模式WIFI_CIPHER_TYPE_AES_CMAC_128, // AES-CMAC-128用于管理帧保护WIFI_CIPHER_TYPE_AES_GCM_256, // AES-GCM-256WPA3-Enterprise 192-bitWIFI_CIPHER_TYPE_AES_GMAC_128, // AES-GMAC-128WIFI_CIPHER_TYPE_AES_GMAC_256, // AES-GMAC-256WIFI_CIPHER_TYPE_UNKNOWN, // 未知/未获取WIFI_CIPHER_TYPE_SMS4, // WAPI 使用的 SMS4 算法WIFI_CIPHER_TYPE_GCMP, // GCMP-128WPA3WIFI_CIPHER_TYPE_GCMP_256, // GCMP-256WPA3-EnterpriseWIFI_CIPHER_TYPE_MAX} wifi_cipher_type_t;Group Cipher又名组密钥加密算法与pairwise_cipher配合使用用于保护广播和组播数据帧。typedef enum {WIFI_CIPHER_TYPE_NONE 0, // 无加密WIFI_CIPHER_TYPE_WEP40, // WEP 40-bitWIFI_CIPHER_TYPE_WEP104, // WEP 104-bitWIFI_CIPHER_TYPE_TKIP, // TKIPWIFI_CIPHER_TYPE_CCMP, // CCMP/AES推荐WIFI_CIPHER_TYPE_TKIP_CCMP, // TKIP CCMP 混合WIFI_CIPHER_TYPE_AES_CMAC_128, // AES-CMAC-128用于管理帧保护 PMFWIFI_CIPHER_TYPE_AES_GCM_256, // AES-GCM-256WPA3-EnterpriseWIFI_CIPHER_TYPE_AES_GMAC_128, // AES-GMAC-128WIFI_CIPHER_TYPE_AES_GMAC_256, // AES-GMAC-256WIFI_CIPHER_TYPE_UNKNOWN,WIFI_CIPHER_TYPE_SMS4, // WAPIWIFI_CIPHER_TYPE_GCMP, // GCMP-128WPA3WIFI_CIPHER_TYPE_GCMP_256, // GCMP-256WIFI_CIPHER_TYPE_MAX} wifi_cipher_type_t;以上三种组合 认证模式和pairwise_cipher和Group Cipher 常用如下5、WIFI路由实验