单片机/MCU论坛
直播中

零知实验室

7年用户 74经验值
擅长:嵌入式技术
私信 关注
[讨论]

ESP32驱动ST7789触摸屏开发指南:LVGL主题设置与示波器面板

一、项目概述
本文介绍如何使用ESP32微控制器驱动ST7789 TFT液晶屏和XPT2046触摸芯片,通过LVGL图形库实现主题切换功能,并开发一个实用的触摸屏示波器应用。项目包含两大核心功能:
引用:

  • LVGL多主题切换:支持8种不同风格的UI主题



  • 示波器功能
    模拟/数字信号采集、触摸控制面板、光标测量系统、自动频率检测

二、硬件准备组件型号说明
主控零知ESP32双核240MHz处理器
屏幕ST7789 2.4寸240×320分辨率
触摸芯片XPT2046电阻式触摸控制器
接线SPI使用硬件SPI接口
接线图
29806dc18a7346caa59180a877bd7f94.png

三、环境搭建
1. 安装库
引用:  lv_arduino v3.0.1
TFT_eSPI
XPT2046_Touchscreen

2. TFT_eSPI配置(User_Setup.h):
  1. ​#define ST7789_DRIVER      // Full configuration option, define additional parameters below for this display
  2. #define TFT_WIDTH  240 // ST7789 240 x 240
  3. #define TFT_HEIGHT 320 // ST7789 240 x 320
  4. #define TFT_MISO 19
  5. #define TFT_MOSI 23   
  6. #define TFT_SCLK 18
  7. #define TFT_CS   15  //Chip select control pin
  8. #define TFT_DC   2   //Data Command control pin
  9. #define TFT_RST  4   //Reset pin (could connect to RST pin)
四、核心代码解析

4.1 LVGL主题设置
  1. // 主题初始化
  2. void setup() {
  3.     lv_test_theme(); // 默认主题
  4.     // 可选主题:
  5.     // lv_test_theme_1(lv_theme_night_init(210, NULL));
  6.     // lv_test_theme_1(lv_theme_material_init(210, NULL));
  7. }
  8. // 显示驱动回调
  9. void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  10.     tft.setAddrWindow(area->x1, area->y1, area->x2, area->y2);
  11.     for(int y=area->y1; y<=area->y2; y++){
  12.         for(int x=area->x1; x<=area->x2; x++){
  13.             tft.writeColor(color_p->full, 1);
  14.             color_p++;
  15.         }
  16.     }
  17.     lv_disp_flush_ready(disp);
  18. }

4.2 触摸驱动(带消抖)
  1. bool my_touchpad_read(lv_indev_drv_t *indev, lv_indev_data_t *data) {
  2.     static lv_coord_t last_x = 0, last_y = 0;
  3.     bool is_touched = ts.touched();
  4.    
  5.     if(is_touched){
  6.         TS_Point p = ts.getPoint();
  7.         // 坐标转换与校准
  8.         last_x = map(p.x, cal_x_min, cal_x_max, 0, 320);
  9.         last_y = map(p.y, cal_y_max, cal_y_min, 0, 240);
  10.         
  11.         // 滑动检测
  12.         if(abs(last_x - prev_x) >5 || abs(last_y - prev_y) >5){
  13.             is_sliding = true;
  14.         }
  15.         
  16.         // 消抖处理
  17.         if(!is_sliding && (millis()-last_touch_time)>CLICK_DEBOUNCE_MS){
  18.             last_touch_time = millis();
  19.         }
  20.     }
  21.     data->point.x = last_x;
  22.     data->point.y = last_y;
  23.     return false;
  24. }

4.3 简易示波器核心逻辑
波形采样:

  1. void takeSample() {
  2.     if(!digitalMode){ // 模拟模式
  3.         uint16_t raw = analogRead(ADC_PIN);
  4.         samplesBuffer[sampleIndex] = raw * amplitudeScale;
  5.     }else{ // 数字模式
  6.         bool state = digitalRead(DIGITAL_PIN);
  7.         samplesBuffer[sampleIndex] = state ? 4095 : 0;
  8.     }
  9.     sampleIndex = (sampleIndex+1) % MAX_SAMPLES;
  10. }


波形绘制:

[code]​
void updateWaveform() {
    waveSprite.fillSprite(BG_COLOR);
    // 绘制网格
    for(int x=0; x
  • b2a38417c8084826b46ed41706ddf6a0.jpeg
  • 512x512 - 副本.png
  • 3ef7a3e0-5bfb-402f-8dd1-f379638427ca.jpg

更多回帖

×
20
完善资料,
赚取积分