主要学习立创ESP32S3 N16R8的基本配置以及其各部件组成
组成结构
| 类别 |
型号 |
参数 |
| 模组 |
ESP32-S3-WROOM-1-N16R8 |
搭载 Xtensa® 32 位 LX7 双核处理器,主频高达 240 MHz,内置SRAM 512kB,外置PSRAM 8MB,外置FLASH 16MB,2.4 GHz Wi-Fi (802.11 b/g/n) 40MHz带宽,Bluetooth 5 (LE) 和 Bluetooth Mesh,集成AI向量指令,加速神经网络计算和信号处理 |
| 显示屏 |
ST7789 |
2.0寸、IPS全视角、分辨率320*240、SPI接口 |
| 触摸屏 |
FT6336 |
电容触摸、I2C接口 |
| 姿态传感器 |
QMI8658 |
三轴加速度+三轴陀螺仪、I2C接口 |
| 音频DAC |
ES8311 |
单通道、I2C接口 |
| 音频ADC |
ES7210 |
四通道(开发板用三个通道)、I2C接口 |
| 音频功放 |
NS4150B |
单声道D类音频放大器 |
| 麦克风 |
ZTS6216 |
配套双路麦克风、模拟输出 |
| 喇叭 |
DB1811AB50 |
1811音腔喇叭、1W |
| USB HUB |
CH334F |
USB2.0 HUB |
| USB转串口 |
CH340K |
波特率最大2Mbps |
| 电源芯片 |
SY8088AAC |
提供双路、每路1A |
| GH1.25接口 |
|
两路外拓传感器接口,可以给外部传感器供电5V和3.3V,可以作为GPIO、CAN、I2C、UART、PWM等接口 |
| TF卡接口 |
|
采用1-SD模式与ESP32连接 |
| Type-C接口 |
|
用于供电、程序下载、程序调试,以及USB数据通信 |
| 按键 |
|
一个复位按键、一个用户自定义按键 |
基础外设
按键Key
样例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| #include <stdio.h> #include <string.h> #include <stdlib.h> #include <inttypes.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "driver/gpio.h"
static QueueHandle_t gpio_evt_queue = NULL;
static void IRAM_ATTR gpio_isr_handler(void* arg) { uint32_t gpio_num = (uint32_t) arg; xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); }
static void gpio_task_example(void* arg) { uint32_t io_num; for(;;) { if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { printf("GPIO[%"PRIu32"] intr, val: %d\n", io_num, gpio_get_level(io_num)); } } }
void app_main(void) { gpio_config_t io_conf = { .intr_type = GPIO_INTR_NEGEDGE, .mode = GPIO_MODE_INPUT, .pin_bit_mask = 1<<GPIO_NUM_0, .pull_down_en = 0, .pull_up_en = 1 }; gpio_config(&io_conf);
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t)); xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL); gpio_install_isr_service(0); gpio_isr_handler_add(GPIO_NUM_0, gpio_isr_handler, (void*) GPIO_NUM_0); }
|
姿态传感器(QMI8658)
I2C控制,地址QMI8658_SENSOR_ADDR= 0x6A
内部集成 3 轴加速度传感器和 3 轴陀螺仪传感器,支持 SPI 和 I2C 通信
I2C的频率为100000
BSP_I2C_NUM为0
| 说明 |
PIN |
| I2C_SCL |
GPIO_NUM_1 |
| I2C_SDA |
GPIO_NUM_2 |
计算倾斜角度(加速度求角度法)

配置qmi8658
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #define QMI8658_SENSOR_ADDR 0x6A enum qmi8658_reg { QMI8658_WHO_AM_I, ...... QMI8658_I2CM_STATUS = 44, ...... QMI8658_dQW_L = 73, ...... QMI8658_RESET = 96 }
void qmi8658_init(void) { uint8_t id = 0;
qmi8658_register_read(QMI8658_WHO_AM_I, &id ,1); while (id != 0x05) { vTaskDelay(1000 / portTICK_PERIOD_MS); qmi8658_register_read(QMI8658_WHO_AM_I, &id ,1); } ESP_LOGI(TAG, "QMI8658 OK!");
qmi8658_register_write_byte(QMI8658_RESET, 0xb0); vTaskDelay(10 / portTICK_PERIOD_MS); qmi8658_register_write_byte(QMI8658_CTRL1, 0x40); qmi8658_register_write_byte(QMI8658_CTRL7, 0x03); qmi8658_register_write_byte(QMI8658_CTRL2, 0x95); qmi8658_register_write_byte(QMI8658_CTRL3, 0xd5); }
esp_err_t qmi8658_register_read(uint8_t reg_addr, uint8_t *data, size_t len) { return i2c_master_write_read_device(BSP_I2C_NUM, QMI8658_SENSOR_ADDR, ®_addr, 1, data, len, 1000 / portTICK_PERIOD_MS); }
esp_err_t qmi8658_register_write_byte(uint8_t reg_addr, uint8_t data) { uint8_t write_buf[2] = {reg_addr, data};
return i2c_master_write_to_device(BSP_I2C_NUM, QMI8658_SENSOR_ADDR, write_buf, sizeof(write_buf), 1000 / portTICK_PERIOD_MS); }
|
求取姿态数值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| typedef struct{ int16_t acc_y; int16_t acc_x; int16_t acc_z; int16_t gyr_y; int16_t gyr_x; int16_t gyr_z; float AngleX; float AngleY; float AngleZ; }t_sQMI8658;
void qmi8658_Read_AccAndGry(t_sQMI8658 *p) { uint8_t status, data_ready=0; int16_t buf[6];
qmi8658_register_read(QMI8658_STATUS0, &status, 1); if (status & 0x03) data_ready = 1; if (data_ready == 1){ data_ready = 0; qmi8658_register_read(QMI8658_AX_L, (uint8_t *)buf, 12); p->acc_x = buf[0]; p->acc_y = buf[1]; p->acc_z = buf[2]; p->gyr_x = buf[3]; p->gyr_y = buf[4]; p->gyr_z = buf[5]; } }
void qmi8658_fetch_angleFromAcc(t_sQMI8658 *p) { float temp;
qmi8658_Read_AccAndGry(p); temp = (float)p->acc_x / sqrt( ((float)p->acc_y * (float)p->acc_y + (float)p->acc_z * (float)p->acc_z) ); p->AngleX = atan(temp)*57.29578f; temp = (float)p->acc_y / sqrt( ((float)p->acc_x * (float)p->acc_x + (float)p->acc_z * (float)p->acc_z) ); p->AngleY = atan(temp)*57.29578f; temp = sqrt( ((float)p->acc_x * (float)p->acc_x + (float)p->acc_y * (float)p->acc_y) ) / (float)p->acc_z; p->AngleZ = atan(temp)*57.29578f; }
|
IO拓展(PAC9557)
外设拓展口,由I2C控制,地址PCA9557_SENSOR_ADDR = 0x19
音频输入(ES7210)
AD0接高电平,AD1接低电平,I2C地址为0x41
ES7210 连接 MIC 负责音频输入,ES8311 只负责音频输出
ES7210 可以连接 4 个 MIC,开发板上连接了 3 个 MIC,MIC1 和 MIC2 接收人说话的声音, MIC3 连接了 ES8311 的输出,用于回声消除。
S3芯片会做回声消除,音响在播放声音的时候,可以说话打断它。
这个原理就是 ES8311 输出的信号,不仅给了喇叭,还给了 ES7210 的 MIC3 输入,ESP32 在接收到 MIC1、MIC2 和 MIC3 的声音后,可以分离出 MIC3,从而进行识别。
本部分例程
-
初始化I2S总线
-
初始化ES7120芯片
-
加载SD卡
-
录制声音
I2S的IO和寄存器配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #define EXAMPLE_ES7210_I2C_ADDR (0x41)
#define EXAMPLE_I2C_NUM (0) #define EXAMPLE_I2C_SDA_IO (1) #define EXAMPLE_I2C_SCL_IO (2)
#define EXAMPLE_I2S_NUM (0) #define EXAMPLE_I2S_MCK_IO (38) #define EXAMPLE_I2S_BCK_IO (14) #define EXAMPLE_I2S_WS_IO (13) #define EXAMPLE_I2S_DI_IO (12)
#define EXAMPLE_I2S_TDM_FORMAT (ES7210_I2S_FMT_I2S) #define EXAMPLE_I2S_CHAN_NUM (2) #define EXAMPLE_I2S_SAMPLE_RATE (48000) #define EXAMPLE_I2S_MCLK_MULTIPLE (I2S_MCLK_MULTIPLE_256) #define EXAMPLE_I2S_SAMPLE_BITS (I2S_DATA_BIT_WIDTH_16BIT) #define EXAMPLE_I2S_TDM_SLOT_MASK (I2S_TDM_SLOT0 | I2S_TDM_SLOT1)
|
标准I2S和TDM_I2S模式
I2S模式
TDM_I2S模式
ES7210工作在I2S模式时,只能采集2个通道,而工作在TDM_I2S模式时,可以采集4个通道
音频输出(ES8311)
主函数包括:
i2s_driver_init() 函数初始化 i2s 接口
es8311_codec_init() 函数初始化 i2c 接口并初始化 es8311 芯片
pca9557_init() 函数初始化 IO 扩展芯片 pca9557
pa_en() 函数用于控制音频功放的打开和关闭,IO1引脚
i2s_music() 函数是创建的任务函数,用于播放音乐
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #define PCA9557_INPUT_PORT 0x00 #define PCA9557_OUTPUT_PORT 0x01 #define PCA9557_POLARITY_INVERSION_PORT 0x02 #define PCA9557_CONFIGURATION_PORT 0x03
#define LCD_CS_GPIO BIT(0) #define PA_EN_GPIO BIT(1) #define DVP_PWDN_GPIO BIT(2)
#define PCA9557_SENSOR_ADDR 0x19
#define SET_BITS(_m, _s, _v) ((_v) ? (_m)|((_s)) : (_m)&~((_s)))
void pca9557_init(void); void lcd_cs(uint8_t level); void pa_en(uint8_t level); void dvp_pwdn(uint8_t level);
void pca9557_init(void) { pca9557_register_write_byte(PCA9557_OUTPUT_PORT, 0x05); pca9557_register_write_byte(PCA9557_CONFIGURATION_PORT, 0xf8); }
|
液晶显示(ST7789+FT6557)
使用SPI驱动,存储到SPIRAM中
液晶屏显示的开关有两个,一个是 esp_lcd_panel_disp_on_off(),一个是 bsp_display_backlight_on()
区别:
esp_lcd_panel_disp_on_off() 用来控制的是液晶屏的驱动芯片 ST7789 中的寄存器,这个寄存器控制液晶屏显示与否。
bsp_display_backlight_on() 用来控制液晶屏 LED 背光,通过调节 PWM 占空比调节亮度,使用的是 LEDC 外设产生的 PWM 信号。
esp_lcd_panel_swap_xy() 函数控制 xy 坐标翻转,第 2 个参数,true 表示翻转,false 表示不翻转。
esp_lcd_panel_mirror() 函数控制 xy 方向是否镜像。第 2 个参数控制 x 方向,第 3 个参数控制 y 方向,true 表示镜像,false 表示不镜像。
实验
IO42 引脚控制液晶屏的背光,低电平亮,如果 IO42 引脚输出 PWM 信号,就可以通过调节占空比,均匀的控制液晶屏的背光亮度
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #define BSP_LCD_BACKLIGHT (GPIO_NUM_42) #define LCD_LEDC_CH LEDC_CHANNEL_0
#define BSP_LCD_PIXEL_CLOCK_HZ (80 * 1000 * 1000) #define BSP_LCD_SPI_NUM (SPI3_HOST) #define LCD_CMD_BITS (8) #define LCD_PARAM_BITS (8) #define BSP_LCD_BITS_PER_PIXEL (16)
#define BSP_LCD_SPI_MOSI (GPIO_NUM_40) #define BSP_LCD_SPI_CLK (GPIO_NUM_41) #define BSP_LCD_SPI_CS (GPIO_NUM_NC) #define BSP_LCD_DC (GPIO_NUM_39) #define BSP_LCD_RST (GPIO_NUM_NC)
|
亮度调节函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| esp_err_t bsp_display_brightness_set(int brightness_percent) { if (brightness_percent > 100) { brightness_percent = 100; } else if (brightness_percent < 0) { brightness_percent = 0; }
ESP_LOGI(TAG, "Setting LCD backlight: %d%%", brightness_percent); uint32_t duty_cycle = (1023 * brightness_percent) / 100; BSP_ERROR_CHECK_RETURN_ERR(ledc_set_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH, duty_cycle)); BSP_ERROR_CHECK_RETURN_ERR(ledc_update_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH));
return ESP_OK; }
|
摄像头(GC0308)
TIP:一般 500W 像素以下的摄像头模块,使用 DVP 接口,以上的使用 MIPI 接口。MIPI 接口速度要高于 DVP 接口。
GC0308 摄像头最大分辨率 640 * 480,30W 像素,工作在 24MHz 频率下,输出 240 *320 分辨率时,可达 30 帧。
实验
PWDN 引脚控制摄像头进入待机模式和工作模式,高电平进入待机模式,低电平进入工作模式
.ledc_channel 和 .ledc_timer中,LEDC 外设用来给某个引脚产生 PWM 信号,这里可以用来产生时钟信号给摄像头的 XCLK 引脚。但是 S3 芯片用不着,因为 S3 芯片的 CAM 外设会产生 XCLK 信号。关于这一点,看 ESP32-S3 的技术参考手册可以了解到。
1 2 3 4 5 6 7
| void app_camera_lcd(void) { xQueueLCDFrame = xQueueCreate(2, sizeof(camera_fb_t *)); xTaskCreatePinnedToCore(task_process_camera, "task_process_camera", 3 * 1024, NULL, 5, NULL, 1); xTaskCreatePinnedToCore(task_process_lcd, "task_process_lcd", 4 * 1024, NULL, 5, NULL, 0); }
|
创建了两个任务,一个任务是摄像头获取画面的任务,一个是液晶屏显示画面的任务。其中,还创建了一个队列信号,摄像头获取到画面,发送队列信号通知 LCD 显示。ESP32S3 是双核处理器,这两个任务,一个定义在 CPU0 上运行,一个定义在 CPU1 上运行,这样可以提高运行速度。xTaskCreatePinnedToCore()函数的最后一个参数,用来定义在哪个 CPU 上运行。
esp_camera_fb_get()函数用来获取一帧摄像头图像,并把获取到的一帧信息返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #define CAMERA_PIN_PWDN -1 #define CAMERA_PIN_RESET -1 #define CAMERA_PIN_XCLK 5 #define CAMERA_PIN_SIOD 1 #define CAMERA_PIN_SIOC 2
#define CAMERA_PIN_D7 9 #define CAMERA_PIN_D6 4 #define CAMERA_PIN_D5 6 #define CAMERA_PIN_D4 15 #define CAMERA_PIN_D3 17 #define CAMERA_PIN_D2 8 #define CAMERA_PIN_D1 18 #define CAMERA_PIN_D0 16 #define CAMERA_PIN_VSYNC 3 #define CAMERA_PIN_HREF 46 #define CAMERA_PIN_PCLK 7
#define XCLK_FREQ_HZ 24000000
|
LVGL
LVGL(Light and Versatile Graphics Library)是一个开源的图形用户界面库,旨在为嵌入式系统提供轻量级、可移植、灵活且易于使用的图形用户界面解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| void bsp_lvgl_start(void) { lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG(); lvgl_port_init(&lvgl_cfg);
disp = bsp_display_lcd_init();
disp_indev = bsp_display_indev_init(disp);
bsp_display_backlight_on(); }
void app_main(void) { bsp_i2c_init(); pca9557_init();
bsp_lvgl_start(); lv_demo_benchmark(); }
|
配置
基础配置
-
Flash = 16MB
-
要存储MP3文件,需要设置FAT文件系统,Default block size = 4096
-
使用SPI,需要设置SPIRAM,应用外存,Octal(8线SPI) Mode PSRAM,80MHz clock speed
-
调用摄像头,设置CPU频率为240MHz,还有如下
-
使用LVGL,需要设置反转颜色,Color settings下的Swap the 2 bytes of…打勾
-
设置其他字体,Font usage可以开启 Enable Monserrat 24等
yml文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| dependencies: lvgl/lvgl: ~8.3.0 espressif/esp_lvgl_port: ~1.4.0 espressif/esp_lcd_touch_ft5x06: ~1.0.6 chmorgan/esp-audio-player: ~1.0.7 chmorgan/esp-file-iterator: 1.0.0 espressif/esp_codec_dev: ~1.3.0 espressif/esp-sr: ~1.6.0 espressif/zlib: ^1.3.0 espressif/esp32-camera: '*' idf: version: ~5.2.5
|
参考
【下载中心】实战派 | 立创开发板技术文档中心
【ESP32-S3的开发】| 1.初识 ESP32-S3_esp32s3引脚图详细解释-CSDN博客
components · GSM-Weather-project/gsm-weather-esp32s3-esp-idf5.0 - 码云 - 开源中国