Rdzleo 4547e9e732 适配ESP32-C3开发板成功
1、原有ESP32-S3功能基本实现,有些小Bug需要修复;
2、RAM内存不够导致Img界面图片显示画质不完整,并且当前未开启蓝牙功能,开机蓝牙功能后RAM内存压力加剧;
2026-02-12 15:45:36 +08:00

303 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "driver/i2c.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_err.h"
#include "esp_log.h"
// #include "esp_pm.h" // 暂时禁用PM
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_flash.h"
#include "esp_check.h"
#include "nvs_flash.h"
#include "lv_demos.h"
#include "string.h"
#include "gpio.h"
#include "wifi.h"
#include "lcd.h"
#include "temp.h"
#include "fatfs.h"
#include "pages.h"
#include "ble.h"
#include "battery.h"
#include "button.h"
#include "sleep_mgr.h"
#include "ui/ui.h"
#include "ui/screens/ui_ScreenSet.h"
#include "ui/screens/ui_ScreenImg.h"
// #include "axis.h"
// #include "esp_bt.h"
// #include "esp_mac.h"
// #include "esp_gap_ble_api.h"
// #include "esp_gattc_api.h"
// #include "esp_gatt_defs.h"
// #include "esp_bt_main.h"
// #include "esp_log.h"
// #include "esp_system.h"
// #include "esp_bt_defs.h"
// #include "freertos/FreeRTOS.h"
// esp_err_t spi_init(void){
// spi_bus_config_t spi_conf = {
// .sclk_io_num = PIN_LCD_CLK,
// .data0_io_num = PIN_LCD_D0,
// .data1_io_num = PIN_LCD_D1,
// .data2_io_num = PIN_LCD_D2,
// .data3_io_num = PIN_LCD_D3,
// .max_transfer_sz = 4096,
// .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_QUAD,
// };
// esp_err_t err = spi_bus_initialize(SPI_LCD_HOST,&spi_conf, SPI_DMA_CH_AUTO);
// spi_device_interface_config_t devcfg = {
// .command_bits = 8,
// .address_bits = 24,
// .mode = 0,
// .clock_speed_hz = 10000000,
// .spics_io_num = PIN_LCD_CS,
// .queue_size = 1,
// .cs_ena_posttrans = 0,
// .flags = SPI_DEVICE_HALFDUPLEX,
// };
// err = spi_bus_add_device(SPI_LCD_HOST, &devcfg, &spi_lcd_handle);
// return err;
// }
// BOOT按键按下处理低功耗模式下只唤醒屏幕正常模式下返回ScreenHome
void boot_btn_handler(int gpio_num, void *usr_data) {
// 检查屏幕是否关闭(低功耗模式)
bool screen_was_off = sleep_mgr_is_screen_off();
if (screen_was_off) {
// 低功耗模式下:只唤醒屏幕,不切换界面
ESP_LOGI("BTN_HANDLER", "BOOT按键低功耗模式仅唤醒屏幕");
sleep_mgr_notify_activity(); // 唤醒屏幕,恢复亮度
} else {
// 正常模式下返回ScreenHome界面
ESP_LOGI("BTN_HANDLER", "BOOT按键正常模式返回ScreenHome");
// 检查当前是否在ScreenImg界面如果是则先隐藏ContainerDle
lv_obj_t *current_screen = lv_scr_act();
if (current_screen == ui_ScreenImg) {
ui_ScreenImg_hide_delete_container();
ESP_LOGI("BTN_HANDLER", "从ScreenImg离开已隐藏ContainerDle");
}
// 先通知活动
sleep_mgr_notify_activity();
// 退出手电筒会降亮度到0但不恢复亮度
bool was_flashlight_active = flashlight_is_active();
uint8_t flashlight_saved_brightness = 0;
if (was_flashlight_active) {
flashlight_saved_brightness = flashlight_get_saved_brightness();
flashlight_exit(); // 降亮度到0删除overlay
ESP_LOGI("BTN_HANDLER", "手电筒已退出亮度降为0");
// 延迟80ms确保overlay完全删除至少15个刷新周期
vTaskDelay(pdMS_TO_TICKS(80));
}
// 切换到ScreenHome界面
_ui_screen_change(&ui_ScreenHome, LV_SCR_LOAD_ANIM_NONE, 0, 0, &ui_ScreenHome_screen_init);
ESP_LOGI("BTN_HANDLER", "已切换到ScreenHome界面");
// 如果刚从手电筒退出,延迟恢复亮度(等待界面渲染完成)
if (was_flashlight_active) {
// 延迟150ms等待Home界面完全渲染
// 不使用强制刷新让LVGL自动处理避免多层同时重绘
vTaskDelay(pdMS_TO_TICKS(150));
pwm_set_brightness(flashlight_saved_brightness);
ESP_LOGI("BTN_HANDLER", "亮度已恢复到%d%%", flashlight_saved_brightness);
}
}
}
// 初始化I2C
esp_err_t i2c_init(void){
i2c_config_t i2c_conf = {
.scl_io_num = PIN_NUM_SCL,
.sda_io_num = PIN_NUM_SDA,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.mode = I2C_MODE_MASTER,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
i2c_param_config(I2C_MASTER_NUM,&i2c_conf);
return i2c_driver_install(I2C_MASTER_NUM, i2c_conf.mode,0,0, 0);
}
// esp_err_t i2c_master_write_slave(uint8_t slave_addr, uint8_t *data_w, size_t size_w) {
// i2c_cmd_handle_t cmd = i2c_cmd_link_create();
// i2c_master_start(cmd);
// i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_WRITE, true);
// i2c_master_write(cmd, data_w, size_w, true);
// i2c_master_stop(cmd);
// esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 100);
// i2c_cmd_link_delete(cmd);
// return ret;
// }
// esp_err_t i2c_master_read_slave(uint8_t slave_addr,uint8_t order, uint8_t *data_r, size_t size_r) {
// i2c_cmd_handle_t cmd = i2c_cmd_link_create();
// i2c_master_start(cmd);
// i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_WRITE, true);
// i2c_master_write_byte(cmd,order,true);
// i2c_master_start(cmd);
// i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_READ, true);
// i2c_master_read(cmd, data_r, size_r, true);
// i2c_master_stop(cmd);
// esp_err_t ret = i2c_master_cmd_begin(I2C_MASTER_NUM, cmd, 100);
// i2c_cmd_link_delete(cmd);
// return ret;
// }
// 初始化NVS
void nvs_init(){
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());// 擦除NVS分区
ret = nvs_flash_init();// 初始化NVS
}
ESP_ERROR_CHECK(ret);// 检查NVS初始化是否成功
// 添加默认图片路径设置
// ============================================================================
nvs_handle_t nvs_handle;
esp_err_t err = nvs_open("config", NVS_READWRITE, &nvs_handle);// 打开NVS配置文件
if (err == ESP_OK) {
size_t imgname_len;// 图片路径长度
err = nvs_get_str(nvs_handle, "img_filename", NULL, &imgname_len);// 获取当前图片路径长度
if (err != ESP_OK) {
// 设置默认图片路径(与放入 spiffs_image 的文件名一致)
const char* default_img = "default.jpg";// 默认图片文件名
err = nvs_set_str(nvs_handle, "img_filename", default_img);// 设置默认图片路径
if (err == ESP_OK) {
nvs_commit(nvs_handle);
ESP_LOGI("NVS", "Set default image: %s", default_img);// 设置默认图片路径
}
}
nvs_close(nvs_handle);// 关闭NVS配置文件
}
// ============================================================================
// nvs_handle_t nvs_handle;
// esp_err_t err;
// err = nvs_open("config", NVS_READWRITE, &nvs_handle);
// if (err != ESP_OK) printf("创建config失败\n");
// int32_t brightness = 80;
// const char* wifi_ssid = "MyWiFi";
// const char* img_filename = "face_1762059331906.jpg";
// err = nvs_set_i32(nvs_handle, "brightness", brightness);
// if (err != ESP_OK) goto close_handle;
// err = nvs_set_str(nvs_handle, "wifi_ssid", wifi_ssid);
// if (err != ESP_OK) goto close_handle;
// err = nvs_set_str(nvs_handle, "img_filename", img_filename);
// if (err != ESP_OK) goto close_handle;
// err = nvs_commit(nvs_handle);
// close_handle:
// nvs_close(nvs_handle);
}
void app_main(void)
{
i2c_init();
ESP_LOGI("MAIN", "1. I2C已初始化");// I2C已初始化
nvs_init();
ESP_LOGI("MAIN", "2. NVS已初始化");// NVS已初始化
// 暂时禁用 Power Management避免动态调频 + Light Sleep 干扰 SPI 时序
// 等LCD显示和触摸功能稳定后再启用
// esp_pm_config_t pm_config = {
// .max_freq_mhz = 160,
// .min_freq_mhz = 40,
// .light_sleep_enable = true
// };
// esp_pm_configure(&pm_config);
lcd_init();
ESP_LOGI("MAIN", "3. LCD已初始化");// LCD已初始化
touch_init();
ESP_LOGI("MAIN", "4. 触摸控制器已初始化");// 触摸控制器已初始化
lvgl_lcd_init();
ESP_LOGI("MAIN", "5. LVGL已初始化");// LVGL已初始化
// LVGL任务创建后下一个tick即运行利用这段时间初始化文件系统
fatfs_init();
ESP_LOGI("MAIN", "6. FATFS文件系统已初始化");// FATFS已初始化
fatfs_remove_nullData("/spiflash");// 移除空数据
fatfs_list_all_filenames("/spiflash",false);// 列出所有文件名
ESP_LOGI("MAIN", "7. SPIFFS处理完成");// SPIFFS处理完成
// =====================================================================
// 显示SquareLine Studio生成的UI界面加锁防止LVGL任务抢占渲染未完成的UI
lvgl_port_lock(0);
ui_init(); // 初始化UI含JPEG解码
lvgl_port_unlock();
ESP_LOGI("MAIN", "8. SquareLine UI已初始化");// SquareLine UI已初始化
// 等待LVGL完成屏幕切换和首帧渲染彻底避免开机闪烁
// ui_init()会创建所有屏幕并加载ScreenHome包括
// 1. JPEG解码约210ms
// 2. 屏幕对象创建和切换
// 3. SPI传输首帧到LCD约200ms
// 增加到250ms确保所有渲染完成后再点亮背光SPI比QSPI慢
vTaskDelay(pdMS_TO_TICKS(250));
// UI渲染完成后先打开LCD显示再点亮背光避免开机闪烁
lcd_disp_on_off(true);
ESP_LOGI("MAIN", "8.1 LCD显示已打开");
pwm_init();
ESP_LOGI("MAIN", "9. PWM背光已初始化");// PWM背光已初始化
// 初始化电池ADC检测并启动监控任务
ESP_ERROR_CHECK(battery_init());
ESP_LOGI("MAIN", "10. 电池ADC已初始化");
battery_monitor_start();
ESP_LOGI("MAIN", "11. 电池监控任务已启动");
// 初始化按键驱动
ESP_ERROR_CHECK(button_init());
ESP_LOGI("MAIN", "12. 按键已初始化");
// 注册BOOT按键回调返回ScreenHome界面
extern void boot_btn_handler(int gpio_num, void *usr_data);
button_on_boot_press(boot_btn_handler, NULL);
ESP_LOGI("MAIN", "12.1 BOOT按键回调已注册");
// 初始化休眠管理器依赖按键和UI必须最后初始化
sleep_mgr_init();
ESP_LOGI("MAIN", "13. 休眠管理器已初始化");
ESP_LOGI("MAIN", "系统初始化完成成功!");// 系统初始化完成成功
// =====================================================================
// // 优先显示测试屏幕
// app_test_display();
// ESP_LOGI("MAIN", "Test screen displayed");
// //=====================================================================
// // // 启动图片循环显示任务
// xTaskCreate(img_loop_task, "img_loop_task", 8192, NULL, 5, NULL);
// ESP_LOGI("MAIN", "图片循环显示任务已启动");
// ESP_LOGI("MAIN", "任务将每3秒循环显示SPIFFS中的所有图片");
// //=====================================================================
// 注释掉静态图片显示,使用任务自动切换
// app_img_display();// 显示图片
// //=====================================================================
}