2298|15

241

帖子

2

TA的资源

纯净的硅(初级)

楼主
 

【DigiKey“智造万物,快乐不停”创意大赛】3、使用lv_port_esp32适配1.69寸触摸屏 [复制链接]

 
  本帖最后由 walker2048 于 2023-11-28 12:37 编辑

前言

我们这次使用的屏幕是淘宝上可以买到的IPS液晶屏,带触摸。由于很多小伙伴都想知道如何快速驱动这款屏幕和触摸,就写了这篇文章。

这款屏幕使用的屏幕驱动是st7789v,触摸驱动是CST816D。

 

一、下载源码并配置st7789屏幕显示

其实LVGL官方是有适配esp32的专用仓库的,虽然也有一年多没更新了,也能用。这个版本使用的是 LVGL 7.9版本,ESP-IDF是4.2版本(我自己电脑上是5.1版本,根据编译错误提示改几个函数就行了)。

 

 

1.1  直接使用命令下载源码,下载后获取子仓源码,全部完成后就可以开始配置了。

git clone --recursive https://github.com/lvgl/lv_port_esp32.git

 

1.2  进入源码目录后,先激活esp-idf环境。加载环境提示如下图

 

1.3 环境加载成功后,将目标设置成esp32-s3

idf.py set-target esp32-s3

1.4 设置完毕后,开启配置模式

idf.py menuconfig

1.4.1 选择屏幕驱动芯片

从前言的描述可以看到,我们使用的这款触摸屏的屏幕驱动是st7789,所以这里选择st7789

  1.4.2 激活反色模式,自定义SPI速度(若不修改SPI速度,默认是20MHz,会有点点卡)

  1.4.3 设置屏幕引脚,这里需要配置6个屏幕引脚,其中RST是不会影响屏幕驱动情况的,大部分情况下不设置问题也不大(未设置时需将屏幕RST引脚接电阻到3.3V拉高)。

  1.4.4 设置屏幕分辨率,开启颜色转换(就是RGB颜色排序问题,反正开启了颜色就正常了,这里不去讲解原理了,我也不会)

  1.4.5 设置屏幕旋转方向。这里选择最后一个(最后跟触摸屏数据要匹配,要么调屏幕,要么改触屏驱动计算方式)

1.4.5 关闭默认demo的自动滑动效果。接下来我们就要移植触屏驱动了,自己滑就行,没必要开这个。

 

  这样改完,直接编译,烧录到设备上,就能看到屏幕亮起来啦。

 

 

二、添加触摸屏驱动

添加触摸屏驱动其实没这么复杂,我们可以去抄袭一下成品的Arduino库,通过阅读库源码,可以看出初始化这个触摸屏并不需要折腾什么,上电后给一个复位信号,然后读取设备ID即可。

其实读取设备ID只是方便调试,例如读取不到ID可能是线接错了之类的。然后就可以定期从触摸屏寄存器里读取触摸数据就行了。

 [![arduino-library-badge](https://www.ardu-badge.com/badge/CST816S.svg?)](https://www.arduinolibraries.info/libraries/cst816-s)

按lvgl驱动的风格写好的代码如下:

2.1 添加cst816.h文件(components/lvgl_esp32_drivers/lvgl_touch/cst816.h)

#ifndef __CST816T_H
#define __CST816T_H

#include <stdint.h>
#include <stdbool.h>
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
    bool inited;
    char product_id[1];
    uint16_t max_x_coord;
    uint16_t max_y_coord;
    uint8_t i2c_dev_addr;
} cst816t_status_t;


#define CST816T_ADDR 0X15
#define CST816T_I2C_SLAVE_ADDR   0x15



void cst816t_init(uint16_t dev_addr);
bool cst816t_read(lv_indev_drv_t *drv, lv_indev_data_t *data);

#endif

#ifdef __cplusplus
}
// #endif
#endif /* __CST816T_H */

2.2 添加cst816.c文件

#include "cst816.h"

#include <driver/i2c.h>
#include <esp_log.h>
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include <lvgl.h>
#else
#include <lvgl/lvgl.h>
#endif

#include "../lvgl_i2c_conf.h"
#include "tp_i2c.h"

#define TAG "CST816T"

static cst816t_status_t cst816t_status;
uint8_t cst816t_read_len(uint16_t reg_addr, uint8_t *data, uint8_t len) {
  uint8_t res = 0;
  res = i2c_master_write_read_device(TOUCH_I2C_PORT, CST816T_ADDR, ®_addr, 1,
                                     data, len, 1000 / portTICK_PERIOD_MS);

  return res;
}

uint8_t cst816t_chipId(void) { return 0; }
static esp_err_t cst816t_get_touch_points_num(uint8_t *touch_points_num) {
  uint8_t res = 0;
  res = cst816t_read_len(0x02, touch_points_num, 1);
  return res;
}

esp_err_t cst816t_read_pos(uint8_t *touch_points_num, uint16_t *x,
                           uint16_t *y) {
  uint8_t data[4];

  cst816t_get_touch_points_num(touch_points_num);
  if (0 == *touch_points_num) {
    *x = 0;
    *y = 0;
    return 1;
  } else {
    cst816t_read_len(0x03, data, 4);

    *x = ((data[0] & 0x0f) << 8) | data[1];
    *y = ((data[2] & 0x0f) << 8) | data[3];
  }

  return ESP_OK;
}

esp_err_t cst816t_i2c_read(uint8_t slave_addr, uint16_t register_addr,
                           uint8_t *data_buf, uint8_t len) {
  i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();

  i2c_master_start(i2c_cmd);
  i2c_master_write_byte(i2c_cmd, (slave_addr << 1) | I2C_MASTER_WRITE, true);
  i2c_master_write_byte(i2c_cmd, register_addr, I2C_MASTER_ACK);

  i2c_master_start(i2c_cmd);
  i2c_master_write_byte(i2c_cmd, (slave_addr << 1) | I2C_MASTER_READ, true);

  i2c_master_read_byte(i2c_cmd, data_buf, I2C_MASTER_NACK);
  i2c_master_stop(i2c_cmd);
  esp_err_t ret =
      i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_PERIOD_MS);
  i2c_cmd_link_delete(i2c_cmd);
  return ret;
}

esp_err_t cst816t_i2c_write8(uint8_t slave_addr, uint16_t register_addr,
                             uint8_t data) {
  i2c_cmd_handle_t i2c_cmd = i2c_cmd_link_create();

  i2c_master_start(i2c_cmd);
  i2c_master_write_byte(i2c_cmd, (slave_addr << 1) | I2C_MASTER_WRITE, true);
  i2c_master_write_byte(i2c_cmd, register_addr, I2C_MASTER_ACK);

  i2c_master_start(i2c_cmd);
  i2c_master_write_byte(i2c_cmd, data, true);

  i2c_master_stop(i2c_cmd);
  esp_err_t ret =
      i2c_master_cmd_begin(TOUCH_I2C_PORT, i2c_cmd, 1000 / portTICK_PERIOD_MS);
  i2c_cmd_link_delete(i2c_cmd);
  return ret;
}

void cst816t_init(uint16_t dev_addr) {
  if (!cst816t_status.inited) {
    cst816t_status.i2c_dev_addr = dev_addr;
    uint8_t data_buf[10];
    esp_err_t ret;

    ESP_LOGI(TAG, "Checking for CST816T Touch Controller ");

    if ((ret = cst816t_i2c_read(dev_addr, 0x15, &data_buf, 1) != ESP_OK)) {
      vTaskDelay(pdMS_TO_TICKS(10));
      ESP_LOGE(TAG, "Error reading from device: %s",
               esp_err_to_name(ret)); // Only show error the first time
                                      // return;
    }
    if ((ret = cst816t_i2c_read(dev_addr, 0xa7, &data_buf, 1) != ESP_OK)) {
      ESP_LOGE(TAG, "Error reading from device: %s",
               esp_err_to_name(ret)); // Only show error the first time
      ESP_LOGE(TAG, "device ID: %02x", data_buf[0]);
      // return;
    }

    cst816t_status.inited = true;
  }
}

bool cst816t_read(lv_indev_drv_t *drv, lv_indev_data_t *data) {

  uint8_t touch_points_num = 0;
  uint16_t x = 0;
  uint16_t y = 0;

  cst816t_read_pos(&touch_points_num, &x, &y);

#if CONFIG_LV_TOUCH_INVERT_X
  x = LV_HOR_RES_MAX - x;
#endif
#if 1
  y = 280 - y;
#endif
#if 1
  int16_t swap_buf = x;
  x = y;
  y = swap_buf;
#endif

  data->point.x = x;
  data->point.y = y;
  if (touch_points_num > 0) {
    data->state = LV_INDEV_STATE_PR;
    ESP_LOGI(TAG, "X=%u Y=%u", data->point.x, data->point.y);
    ESP_LOGV(TAG, "X=%u Y=%u", data->point.x, data->point.y);
  } else {
    data->state = LV_INDEV_STATE_REL;
  }

  return false;
}

 

2.3 在touch_driver.c文件里添加对应的初始化代码和触屏读取函数调用,如果不添加,就没办法获取到触屏数据。

components/lvgl_esp32_drivers/lvgl_touch/touch_driver.c

void touch_driver_init(void)
{
#if defined (CONFIG_LV_TOUCH_CONTROLLER_XPT2046)
    xpt2046_init();
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
    ft6x06_init(FT6236_I2C_SLAVE_ADDR);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
    stmpe610_init();
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
    adcraw_init();
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
    /* nothing to do */
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
    ra8875_touch_init();
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_CST816)
    cst816t_init(CST816T_I2C_SLAVE_ADDR);
#endif
}

bool touch_driver_read(lv_indev_drv_t *drv, lv_indev_data_t *data)
{
    bool res = false;

#if defined (CONFIG_LV_TOUCH_CONTROLLER_XPT2046)
    res = xpt2046_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
    res = ft6x36_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
    res = stmpe610_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
    res = adcraw_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
    res = FT81x_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
    res = ra8875_touch_read(drv, data);
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_CST816)
    res = cst816t_read(drv, data);
#endif

    return res;
}

2.4 touch_driver.h 添加cst816.h头文件引用。如果不添加会有编译错误,提示找不到上一步加到代码里的两个函数。

components/lvgl_esp32_drivers/lvgl_touch/touch_driver.h

#if defined (CONFIG_LV_TOUCH_CONTROLLER_XPT2046)
#include "xpt2046.h"
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
#include "ft6x36.h"
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
#include "stmpe610.h"
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
#include "adcraw.h"
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_FT81X)
#include "FT81x.h"
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_RA8875)
#include "ra8875_touch.h"
#elif defined (CONFIG_LV_TOUCH_CONTROLLER_CST816)
#include "cst816.h"
#endif

2.5 在构建系统配置文件里添加cst816驱动文件配置,如果不添加,在链接阶段会提示找不到cst816t_read和cst816t_init这两个符号

components/lvgl_esp32_drivers/CMakeLists.txt

# Add touch driver to compilation only if it is selected in menuconfig
if(CONFIG_LV_TOUCH_CONTROLLER)
    list(APPEND SOURCES "lvgl_touch/touch_driver.c")
    list(APPEND LVGL_INCLUDE_DIRS lvgl_touch)

    # Include only the source file of the selected
    # touch controller.
    if(CONFIG_LV_TOUCH_CONTROLLER_XPT2046)
        list(APPEND SOURCES "lvgl_touch/xpt2046.c")
    elseif(CONFIG_LV_TOUCH_CONTROLLER_FT6X06)
        list(APPEND SOURCES "lvgl_touch/ft6x36.c")
    elseif(CONFIG_LV_TOUCH_CONTROLLER_STMPE610)
        list(APPEND SOURCES "lvgl_touch/stmpe610.c")
    elseif(CONFIG_LV_TOUCH_CONTROLLER_ADCRAW)
        list(APPEND SOURCES "lvgl_touch/adcraw.c")
    elseif(CONFIG_LV_TOUCH_CONTROLLER_FT81X)
        list(APPEND SOURCES "lvgl_touch/FT81x.c")
    elseif(CONFIG_LV_TOUCH_CONTROLLER_RA8875)
        list(APPEND SOURCES "lvgl_touch/ra8875_touch.c")
    elseif(CONFIG_LV_TOUCH_CONTROLLER_CST816)
        list(APPEND SOURCES "lvgl_touch/cst816.c")
    endif()

    if(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_SPI)
        list(APPEND SOURCES "lvgl_touch/tp_spi.c")
    elseif(CONFIG_LV_TOUCH_DRIVER_PROTOCOL_I2C)
        list(APPEND SOURCES "lvgl_touch/tp_i2c.c")
    endif()
endif()

 

三、修改Kconfig文件

由于我们添加了CST816的相关源码 ,按LVGL的风格配置好Kconfig信息,用来添加触摸屏的引脚和部分配置。

(文件路径components/lvgl_esp32_drivers/lvgl_touch/Kconfig)

将第3行到40行修改成以下内容,主要就是添加CST816的配置信息

    config LV_TOUCH_CONTROLLER
	int
	default 0 if LV_TOUCH_CONTROLLER_NONE
	default 1 if LV_TOUCH_CONTROLLER_XPT2046
	default 2 if LV_TOUCH_CONTROLLER_FT6X06
	default 3 if LV_TOUCH_CONTROLLER_STMPE610
        default 4 if LV_TOUCH_CONTROLLER_ADCRAW
        default 5 if LV_TOUCH_CONTROLLER_FT81X
        default 6 if LV_TOUCH_CONTROLLER_RA8875
    default 7 if LV_TOUCH_CONTROLLER_CST816

    choice
	prompt "Select a touch panel controller model."
	default LV_TOUCH_CONTROLLER_NONE
	help
	    Select the controller for your touch panel.

	config LV_TOUCH_CONTROLLER_NONE
	    bool "None"
	config LV_TOUCH_CONTROLLER_XPT2046
            select LV_TOUCH_DRIVER_PROTOCOL_SPI
            bool "XPT2046"
	config LV_TOUCH_CONTROLLER_FT6X06
            select LV_TOUCH_DRIVER_PROTOCOL_I2C
            bool "FT6X06"
        config LV_TOUCH_CONTROLLER_STMPE610
            select LV_TOUCH_DRIVER_PROTOCOL_SPI
            bool "STMPE610"
        config LV_TOUCH_CONTROLLER_ADCRAW
            select LV_TOUCH_DRIVER_ADC
            bool "ADCRAW"
        config LV_TOUCH_CONTROLLER_FT81X
            select LV_TOUCH_DRIVER_PROTOCOL_SPI
            bool "FT81X"
        config LV_TOUCH_CONTROLLER_RA8875
            select LV_TOUCH_DRIVER_DISPLAY
            bool "RA8875"
    config LV_TOUCH_CONTROLLER_CST816
        select LV_TOUCH_DRIVER_PROTOCOL_I2C
        bool "CST816"
        select LV_TOUCH_DRIVER_DISPLAY
            bool "CST816"
    endchoice

在倒数第二行添加 CST816的额外配置内容,并按原理图的引脚指定好默认引脚。


    menu "Touchpanel Configuration (CST816)"
        depends on LV_TOUCH_CONTROLLER_CST816

        config LV_TOUCH_I2C_SDA
            int
            prompt "GPIO for SDA (I2C)"
            range 0 39 if IDF_TARGET_ESP32
            range 0 43 if IDF_TARGET_ESP32S2

            default 14
            help
            Configure the I2C touchpanel SDA pin here.

        config LV_TOUCH_I2C_SCL
            int "GPIO for clock signal SCL (I2C)"
            range 0 39 if IDF_TARGET_ESP32
            range 0 43 if IDF_TARGET_ESP32S2
            
            default 13
            help
            Configure the I2C touchpanel SCL pin here.

        config LV_TOUCH_PIN_IRQ
            int "GPIO for IRQ (Interrupt Request)"
            range 0 39 if IDF_TARGET_ESP32
            range 0 43 if IDF_TARGET_ESP32S2
	    
            default 21 if LV_PREDEFINED_PINS_38V4
            default 21
            help
            Configure the touchpanel IRQ pin here.

        config LV_TOUCH_INVERT_X
            bool
            prompt "Invert X coordinate value"
            default n

        config LV_TOUCH_INVERT_Y
            bool
            prompt "Invert Y coordinate value"
            default n

    endmenu

然后编译好源码,就可以上传到板子上测试了。测试视频如下,触摸还是比较流畅的。

 

 

最新回复

楼主有空开微雪的工程   详情 回复 发表于 2024-9-5 23:14
点赞 关注
 
 

回复
举报

241

帖子

2

TA的资源

纯净的硅(初级)

沙发
 

touch

视频在这里

点评

稳定在33FPS,看来还不错。  详情 回复 发表于 2023-11-29 17:27
 
 
 

回复

6585

帖子

9

TA的资源

版主

板凳
 

就怕这种库的适配,要是没有教程,真心不知道哪里出问题了

点评

感觉玩多了RTOS就熟悉了,我也是第一次折腾这个,也没啥能参考的教程。一个多小时就搞定了。  详情 回复 发表于 2023-11-29 15:54
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

241

帖子

2

TA的资源

纯净的硅(初级)

4
 
秦天qintian0303 发表于 2023-11-28 13:24 就怕这种库的适配,要是没有教程,真心不知道哪里出问题了

感觉玩多了RTOS就熟悉了,我也是第一次折腾这个,也没啥能参考的教程。一个多小时就搞定了。

 
 
 

回复

7277

帖子

2

TA的资源

版主

5
 

稳定在33FPS,看来还不错。

 
 
 

回复

7277

帖子

2

TA的资源

版主

6
 

居然支持那么多种屏幕芯片驱动。

点评

没支持的屏也可以去抄一下Arduino的库,难度不算大  详情 回复 发表于 2023-11-29 19:11
 
 
 

回复

241

帖子

2

TA的资源

纯净的硅(初级)

7
 
wangerxian 发表于 2023-11-29 17:28 居然支持那么多种屏幕芯片驱动。

没支持的屏也可以去抄一下Arduino的库,难度不算大

点评

最近正准备抄Arduino的SD卡库呢。  详情 回复 发表于 2023-11-30 10:35
 
 
 

回复

7277

帖子

2

TA的资源

版主

8
 
walker2048 发表于 2023-11-29 19:11 没支持的屏也可以去抄一下Arduino的库,难度不算大

最近正准备抄Arduino的SD卡库呢。

 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

9
 
楼主,你好,按照你的方法移植cst816T的驱动,编译发现缺头文件,尤其是这个tp_i2c.h ,请问在哪?#include "../lvgl_i2c_conf.h" #include "tp_i2c.h"
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

10
 
新手小白一枚,按照上面你的方法,把显示给搞定了,谢谢。触摸部分沿用你的方法,编译缺lvgl_i2c_conf.h和tp_i2c.h两个头文件,请楼主帮忙

点评

发一下具体报错的详细信息看看,我印象中没有这种错误  详情 回复 发表于 2024-8-30 13:28
 
 
 

回复

241

帖子

2

TA的资源

纯净的硅(初级)

11
 
lion101 发表于 2024-8-29 23:33 新手小白一枚,按照上面你的方法,把显示给搞定了,谢谢。触摸部分沿用你的方法,编译缺lvgl_i2c_conf.h和t ...

发一下具体报错的详细信息看看,我印象中没有这种错误

 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

12
 
walker2048 发表于 2024-8-30 13:28 发一下具体报错的详细信息看看,我印象中没有这种错误

编译cst816.c时报错,找不到vgl_i2c_conf.h 和tp_i2c.h

我用的是lvgl8.3,我看你用的是7.9。会不会和版本有关系?这个两个头文件我在我机器里的lvgl文件夹里也是搜索不到

点评

8.3也可以不用lvgl的内置驱动吧,你是用微雪的板子还是自己做的?如果是微雪的,我晚点会开源一个工程  详情 回复 发表于 2024-9-5 09:06
 
 
 

回复

241

帖子

2

TA的资源

纯净的硅(初级)

13
 
lion101 发表于 2024-9-5 01:18 编译cst816.c时报错,找不到vgl_i2c_conf.h 和tp_i2c.h 我用的是lvgl8.3,我看你用的是7.9。会不会和版 ...

8.3也可以不用lvgl的内置驱动吧,你是用微雪的板子还是自己做的?如果是微雪的,我晚点会开源一个工程

点评

楼主有空开微雪的工程  详情 回复 发表于 2024-9-5 23:14
用的是微雪的板子,我看了下,老版本lvgl的内置驱动有我缺少的那两个头文件  详情 回复 发表于 2024-9-5 23:12
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

14
 
walker2048 发表于 2024-9-5 09:06 8.3也可以不用lvgl的内置驱动吧,你是用微雪的板子还是自己做的?如果是微雪的,我晚点会开源一个工程

用的是微雪的板子,我看了下,老版本lvgl的内置驱动有我缺少的那两个头文件

 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

15
 
walker2048 发表于 2024-9-5 09:06 8.3也可以不用lvgl的内置驱动吧,你是用微雪的板子还是自己做的?如果是微雪的,我晚点会开源一个工程

楼主有空开微雪的工程

点评

https://gitee.com/walker2048/esp32_169t/tree/master/2_throughput_test/lv_esp32 这个是之前无聊折腾的espnow吞吐量测试案例,适配的lvgl 9.1,最近暂时没空折腾,先看看这个能不能用  详情 回复 发表于 2024-9-5 23:30
 
 
 

回复

241

帖子

2

TA的资源

纯净的硅(初级)

16
 
lion101 发表于 2024-9-5 23:14 楼主有空开微雪的工程

https://gitee.com/walker2048/esp32_169t/tree/master/2_throughput_test/lv_esp32

这个是之前无聊折腾的espnow吞吐量测试案例,适配的lvgl 9.1,最近暂时没空折腾,先看看这个能不能用

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表