ESP32-S3 和 ESP32 一样是一款同时支持WIFI和蓝牙功能,可以说是专为物联网而生的一款Soc,应用领域贯穿移动设备、可穿戴电子设备、智能家居等,在2,4GHz频带支持20MHz和40MHz频宽,和以往 ESP32 不一样的是,蓝牙除了支持BLE以外,目前支持 Bluetooth 5 和 Bluetooth mesh,更多的GPIO口使其能控制的外设达到更多,全速USB OTG支持直接通过USB协议与芯片进行通信
对于ESP各个系列的芯片介绍,官方网站提供了最详细的参考:https://www.espressif.com/zh-hans/products/socs
(以下内容以ESP32-S3为例,展开介绍)
其中根据用户需要的资源或方案,可以在该网站中,选择合适的产品,以下,则是ESP32-S3芯片对应不同大小的 FLASH 和 PSRAM 进行封装的模组命名和内置芯片的对应关系
普及一下手册中讲到的 SPI、Dual SPI 和 Quad SPI
SPI:标准SPI,是一种同步串行通信协议,支持一主多从,主设备启动与从设备进行同步通信,完成数据的交换。SPI是一种高速全双工同步通信总线,标准的SPI仅使用4个引脚(信号):CLK , CS , MOSI , MISO
Dual SPI :一般只针对 SPI FLASH 而言(并不针对所有外设),而基于这个对象,全双工并不常用,MOSI 和 MISO 被扩展用于半双工加速数据传输,对于 Dual SPI FLASH 设备,发送一个命令字节使其进入 dual 模式,MOSI 变成 DIO0,MISO 变成 DIO1,致使一个时钟周期传输 2bit 数据
Quad SPI:同样针对 SPI FLASH ,Qual SPI 又增加了两IO(DIO2、DIO3),可以在一个时钟周期中传输 4bit 数据;
对于 SPI FLASH 而言,用于进行数据传输的模式就有以上三种类型,对应着3线、4线、6线的传输方式,而相同时钟周期下,线的数量和传输速度成正相关
以上,为什么要介绍这三种 SPI FLASH 接口呢?玩过 ESP 系列的大伙应该都知道,这是 ESP 模组封装的惯用做法,ESP32-S3 芯片内置有 512 KB SRAM(用于数据和指令存储)、384 KB ROM 存储空间(用于程序启动和内核功能调用),对于 FLASH 则支持使用外挂的形式,持多个外部 SPI、Dual SPI、 Quad SPI、Octal SPI、QPI、OPI flash 和片外 RAM
接下来的硬件介绍 ESP32-S3-DevKitC-1 板,都基于当前官方连接:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/hw-reference/esp32s3/user-guide-devkitc-1.html
这里抽(能突出板子的特点的)几个板载的模组/外设,来贴图讲解,其他包括电源、USB转串口,按键等,都和其他开发板一致,都是为了方便大家在开发过程中进行使用而被设计
具体板子和管脚的信息大家可以打开上面的网址,会查看得比较详细,或者这个PDF里,会有大家想找的管脚功能描述:(这是芯片手册,所有的管脚描述都是针对芯片而言)
https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_cn.pdf
这些管脚是和芯片复位状态有关的引脚,在芯片的系统复位(上电、RTC 看门狗、欠压、模拟超级看门狗 、晶振时钟毛刺检测)等复位过程中,Strapping 管脚对自己电平采样并存储到锁存器,并一直保持到芯片掉电或关闭
GPIO0:决定系统启动模式(0:下载模式 | 1: SPI启动模式)
当处于GPIO0 上拉,处于SPI启动模式时,GPIO46 电平可以是任意;
当处于GPIO0 下拉,处于下载模式时,GPIO46 电平只能是低电平(GPIO46高电平不可用);
GPIO45:是决定VDD_SPI 电压的其中一项(默认下拉),另一项是 eFuse 中 VDD_SPI_TIEH 。
eFuse 中 EFUSE_VDD_SPI_FORCE 选择决定方式:(0 : 由 GPIO45 的 strapping 值决定 | 1 : 由 eFuse 中 EFUSE_VDD_SPI_TECH 决定)
GPIO3:切换CPU内部的JTAG信号来源
当eFuse的 EFUSE_DIS_USB_SERIAL_JTAG 和 EFUSE_DIS_USB_OTG 同时为0,ROM Code打印至 USB Serial/JTAG 控制器,否则打印至 UART,此时 GPIO46 与 EFUSE_UART_PRINT_CONTROL 一起控制 ROM code 打印:
0:上电正常打印,不受GPIO46控制
1:if ( GPIO46 == 0 ) 上电正常打印 else 上电不打印
2:if ( GPIO46 == 0 ) 上电不打印 else 上电正常打印
3:上电不打印,不受GPIO46 控制
如果在验证电路的过程中,发现启动模式产生异常,优先使用示波器检测当前的上电 Strapping 管脚电平以及时序波形是否满足要求
I. 原则上不能把 Strapping 引脚用于其他地方,否则会引起启动状态的异常
II.另外,因为模组内置的 FLASH 和 PSRAM 的缘故,占用了部分管脚,不建议使用这部分引脚,具体模组和管脚占用关系,参考下表
III.具体芯片管脚号和其具体功能的对应关系,参考下表
ESP-IDF 是乐鑫官方的物联网开发框架,适用于 ESP32、ESP32-S 和 ESP32-C 系列 SoC
框架内的详细组件大家可以参考:https://www.espressif.com/zh-hans/products/sdks/esp-idf
下面先说一下环境搭建的注意事项,在如何搭建的这一部分,如果觉得说的不够详细,可以参考一下官方环境搭建教程:
https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/get-started/index.html#get-started-get-prerequisites
先说一下本人,目前在 Linux 系统下,使用 GNU Make 或 CMake 构建系统对应的 ESP-IDF(其中包括ESP8266、ESP32、ESP32S3 的 esp-idf ,另外还有乐鑫音频框架 esp-adf ),而其中 esp-idf 也有几个版本,为了环境支持各个版本,能随时切换,所以选择在 Linux 系统下进行SDK下载、编译环境的单独安装,并没有选择诸如 Eclipse,VSCode 插件等 IDE。而是通过把SDK下载到不同的文件夹进行管理。
之所以推荐这种方式,是因为它的安装和环境变量的设置方式简单,可以完全根据官方的 Linux 开发环境进行安装(下面都以UBuntu为例)https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32s3/get-started/index.html#id3
I.安装准备(首先需要下载安装 Linux 平台工具链,因为编译 ESP-IDF 需要以下软件包)
sudo apt-get install git wget flex bison gperf python3 python3-pip python3-setuptools cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
II.获取ESP-IDF(做好文件夹管理好自己的SDK(选择SDK克隆路径,通过cd指令进入用户的路径))
git clone --recursive https://github.com/espressif/esp-idf.git
III.设置工具(进入对应 esp-idf 文件夹,打开终端键入)
./install.sh
可一次性为所有支持的目标芯片安装工具,当然也可以选择对单独的芯片进行安装
IV.设置环境变量(进入对应 esp-idf 文件夹,打开终端键入)
. ./export.sh
vi ~/.bashrc
想使用哪个SDK,编译不同工程的时候,可以解放注释,并把不用的SDK环境变量注释掉,最终
source ~/.bashrc
再进入相应的SDK,再次执行 III、IV操作,即可完成 SDK 切换
其他的 IDE 环境作者接触过的 VSCode 插件,可以直接在拓展栏下搜索 esp,即可搜出
具体安装方法可以参考这个链接https://www.youtube.com/watch?v=Lc6ausiKvQM&feature=youtu.be
至于Eclipse下的集成开发环境,安装SDK和环境变量的设置不难,用户也可以尝试使用
首先进入SDK提供的案例工程,设置当前硬件所使用的MCU,进行编译,当然如果你有其他的硬件配置需要更改,可以通过idf.py menuconfig 或者 make menuconfig 进行界面的配置
cd esp-idf/examples/get-started/hello_world
idf.py set-target esp32s3
idf.py build
拷贝example文件夹下的工程到其他文件夹,由于我们在上面已经定义好了esp-idf 的环境变量,所以最后在编译项目工程时,都会依靠项目工程下的 CMakeList 找到环境变量中的 esp-idf ,继而链接上我们的组件等等
为方便对工程文件进行查看和编辑,我们可以使用 VS Code
由于官网下载的SDK还没完善,当前所有的编译工具和调试工具等,都只支持调用 python 指令,
在VS Code环境下添加工程时(如果工程有自定义的头文件路径),会经常发生无法打开源文件 xxx.h,这是由于VSCode这个编辑器下需要安装C/C++的扩展工具,并且有指定头文件的路径,才能被索引打开。
I.首先需要安装C/C++的扩展工具
II.安装完成后,需要添加头文件路径以告知编辑器
此时可以通过 Ctrl+Shift+p 的快捷键,打开C/C++的文件配置系统,直接在“Json格式的配置页面中,找到includePath”键,添加项目所需要的头文件路径的键值
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/main/include",
"${workspaceFolder}/components/LED/include",
"${IDF_PATH}/components/esp_common/include",
"${IDF_PATH}/components/esp_system/include",
"${IDF_PATH}/components/esp_hw_support/include",
"${IDF_PATH}/components/freertos/FreeRTOS-Kernel/include",
"${IDF_PATH}/components/freertos/esp_additions/include/freertos",
"${IDF_PATH}/components/freertos/FreeRTOS-Kernel/portable/xtensa/include",
"${IDF_PATH}/components/xtensa/include",
"${IDF_PATH}/components/xtensa/esp32s3/include",
"${IDF_PATH}/components/mdns/host_test/components/esp_system_protocols_linux/include",
"${IDF_PATH}/components/newlib/platform_include",
"${IDF_PATH}/components/newlib/platform_include/sys",
"${IDF_PATH}/components/heap/include",
"${IDF_PATH}/components/esp_rom/include",
"${IDF_PATH}/components/soc/esp32s3/include",
"${IDF_PATH}/components/spi_flash/include",
"${IDF_PATH}/components/esp_hw_support/include",
"${IDF_PATH}/components/hal/include",
"${IDF_PATH}/components/hal/esp32s3/include",
"${IDF_PATH}/components/soc/include",
"${IDF_PATH}/components/esp_timer/include",
"${IDF_PATH}/components/log/include",
"${IDF_PATH}/components/nvs_flash/include",
"${IDF_PATH}/components/driver/include"
],
"defines": [
"__XTENSA__"
],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu11",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x64",
}
],
"version": 4
}
III.完成头文件路径的添加后,可以重启VScode,便可以定位其头文件
IV.如果曾经解决过问题,而后来又在VScode拓展中安装了CMake Tools,给项目配置了使用CMake工具时,头文件会提示:基于 configurationProvider 设置提供的信息检测到#include 有误,…,想返回以前的配置,可以通过 Ctrl+Shift+p ,把"configurationProvider": “ms-vscode.cmake-tools”,键和键值删掉,就能恢复(记得也要把上一个键值的","去掉)
I.新建的部件需要在其文件目录下建立CMakeList.txt,并把其引用的源文件、头文件、esp-idf 组件等以键值形式添加至其中
举个例子,上面我在项目下新建了 components 文件夹,并以各个板载组件区分开应用,第一个组件是LED(即新建一个LED文件夹),因为用到了 ESP32-S3-DevKitC-1 中的RGB灯,在链接工具不完善的情况下把 idf 的源文件拷贝到和 LED.c 的同一级目录下,头文件则用 include 文件夹存起来
这里只讲移植,基于RMT是什么内容以后到系列课程再讲;
回到上面的 CMakeList.txt 的编写规则,源文件就只有两个,把它用一个 LED_SRCS 变量名代替,并且把用到的头文件也定义其他变量名,最后通过 idf_component_register 注册所有组建,因为里面用到了 idf 里的 nvs 组件,它的包含方式比较另类,大家可以先从 idf 组建的文件夹下,拷贝下来,先进行模仿学习,具体规则参考:https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/build-system.html#esp-idf-cmake-api
区分前面第⑦点讲的内容,是把头文件索引告诉VS Code,使它能快速帮我们定位到 用户所包含的头文件,但实际上,VS Code 和编译器是完全不同的东西,我们需要通过第⑧点的操作,告知编译器我们所需要链接的内容和组件,才能实现正常编译
启动 idf.py 脚本,-p 指定相应USB接口,flash 执行烧录操作,默认烧录速率 460800
idf.py -p /dev/ttyUSB0 flash
另外,用户可以自定义烧录速率,只需要在 flash 参数之前,加上一项 -b ,后面跟上指定波特率
idf.py -p /dev/ttyUSB0 -b 921600 flash
启动 idf.py 脚本,-p 指定相应的USB接口,monitor 执行监视操作,默认监视波特率 115200
idf.py -p /dev/ttyUSB0 monitor
如果烧录或者监视过程中遇到这种失败的错误,首先需要检查是否串口是当前的串口号,是否有串口的操作权限,可直接将串口权限设置至“可读可写可执行”最高权限
检查串口号这个得用户自己去做检查了,假设我这个USB设备名是ttyUSB0,设置串口操作权限可以通过以下的指令设置成最高权限,则可执行烧录和监视
sudo chmod 777 /dev/ttyUSB0