✨ 新增功能 - 按键驱动模块:GPIO中断+软件去抖,支持BOOT和KEY2按键事件回调 - 休眠管理器:10秒无操作自动休眠,触摸/按键唤醒,UI集成开关 - 电池电量监控:GPIO3 ADC实时检测,ScreenSet界面圆弧显示 🐛 Bug修复 - 修复FreeRTOS任务栈溢出导致内存损坏(battery任务栈2048→4096) - 修复图片文件名损坏问题(改用静态缓冲区替代动态分配) - 修复触摸中断引脚配置错误(GPIO4→GPIO5,匹配V1.0硬件) - 修复开机闪烁问题(调整背光初始化时序,UI渲染后再点亮) 🎨 界面优化 - ScreenSet恢复为标准Screen切换方式(移除浮动面板架构) - 亮度调节支持0%(完全关闭)和10-100%范围 - ScreenHome界面电量显示独立(不关联实时电量) - 手势导航优化:下拉显示设置,上滑返回主界面 ⚡ 性能优化 - 启动时间优化:从650ms缩短至170ms - 内存管理优化:图片列表使用静态数组(10×32字节) - 任务栈配置调优:battery 4096, button 3072, sleep_mgr 3072 📝 其他改进 - CMakeLists.txt添加新模块编译配置 - 添加硬件版本兼容性注释(GPIO引脚说明) - 完善函数注释和错误日志输出 - sdkconfig配置更新 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
227 lines
8.3 KiB
C
227 lines
8.3 KiB
C
#include "driver/i2c.h"
|
||
#include "driver/spi_master.h"
|
||
#include "esp_err.h"
|
||
#include "esp_log.h"
|
||
#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 "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;
|
||
// }
|
||
|
||
// 初始化I2C
|
||
esp_err_t i2c_init(void){
|
||
i2c_config_t i2c_conf = {
|
||
.scl_io_num = PIN_NUM_SCL,
|
||
.sda_io_num = PIN_NUM_SDA,
|
||
.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已初始化
|
||
|
||
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界面
|
||
ui_init(); // 初始化UI(含JPEG解码)
|
||
ESP_LOGI("MAIN", "8. SquareLine UI已初始化");// SquareLine UI已初始化
|
||
|
||
// 等待LVGL完成屏幕切换和首帧渲染,彻底避免开机闪烁
|
||
// ui_init()会创建所有屏幕并加载ScreenHome,包括:
|
||
// 1. JPEG解码(约210ms)
|
||
// 2. 屏幕对象创建和切换
|
||
// 3. QSPI传输首帧到LCD(约100ms)
|
||
// 增加到150ms确保所有渲染完成后再点亮背光
|
||
vTaskDelay(pdMS_TO_TICKS(150));
|
||
|
||
// UI渲染完成后再点亮背光,避免开机闪烁旧画面
|
||
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. 按键已初始化");
|
||
|
||
// 初始化休眠管理器(依赖按键和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();// 显示图片
|
||
// //=====================================================================
|
||
}
|