Rdzleo f9dc7d4861 feat: 触屏版迁移到按键版,两键实现全部交互功能
1. 按键驱动重构:GPIO中断+手动去抖 → iot_button组件(单击/双击/长按)
2. 新增key_nav按键导航管理器:上下文状态机 + Set界面焦点蓝色边框高亮
3. 移除所有触摸手势/点击事件(ScreenHome/ScreenImg/ScreenSet)
4. 应援灯颜色切换优化:DISPOFF→直接写GRAM→DISPON,消除分band刷新
5. 亮度调节按键化:BOOT +10% / KEY -10% / KEY长按退出
6. 休眠管理适配:按键唤醒统一由key_nav处理
7. 新增迁移总结文档 docs/touch-to-button-migration.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 14:57:14 +08:00

254 lines
9.3 KiB
C
Raw Permalink 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 "key_nav.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;
// }
// 按键处理已移至key_nav模块key_nav.c支持单击/双击/长按和多界面上下文导航
// 初始化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. 按键已初始化");
// 初始化休眠管理器依赖按键和UI
sleep_mgr_init();
ESP_LOGI("MAIN", "12.1 休眠管理器已初始化");
// 初始化按键导航管理器注册BOOT/KEY2所有按键回调必须在button_init和sleep_mgr_init之后
key_nav_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();// 显示图片
// //=====================================================================
}