这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【eDIY】蓝牙低功耗温湿度计02过程贴:温湿度信息采集

共1条 1/1 1 跳转至

【eDIY】蓝牙低功耗温湿度计02过程贴:温湿度信息采集

助工
2026-06-10 19:59:32     打赏

【eDIY】蓝牙低功耗温湿度计 02 过程贴:温湿度信息采集任务说明

SHT30 传感器驱动开发 • 完成 NXP FRDM-MCXW71 开发板与 SHT30 传感器的 I2C 物理连接 • 实现温度与湿度数据读取函数, 在串口终端打印原始数据与解析后的温湿度值,格式为:Temperature: 23.5°C, Humidity: 45.2%RH

我没有采购这类传感器,而使用盛思锐出品的I2C接口的SEN66传感器,它支持9种数据,是目前市面上集成度最高的空气质量监测模组之一。

SEN66 技术特点

  • 高度集成:9 种传感器功能集成在一个模组中,无需多个独立传感器,节省 PCB 空间和 BOM 成本

  • I²C 接口:通过 I²C 总线通信,与 MCU 连接简单

  • 低功耗:适合电池供电的便携式设备

  • 高精度:采用 Sensirion 成熟的 SHT 温湿度传感技术和激光散射颗粒物检测技术

  • 算法内置:VOC 和 NOx 指数通过内置算法从原始气体传感器数据计算得出

SEN66 典型应用场景

  • 室内空气质量监测仪

  • 智能家居环境监控

  • 工业环境安全监测

  • 物联网(IoT)环境监测终端

  • 楼宇自动化系统

任务实现

此任务规划如下:

  • SEN66 通过I2C驱动,采集9种传感器数据并通过串口打印

  • OLED 显示屏初始化,显示温湿度信息

I2C 资源介绍

这两个设备都通过I2C驱动,而 FRDM-MCXW71 开发板上的I2C资源如下,在板载的 Arduino 接口和 Mikro Bus 接口上有一个共同的 I2C1_SDA, I2C1_SCL。

Image

Image

在 UM12063.pdf 文档中有说明,MCXW71 支持2个LPI2C 模块,分别是 LPI2C0 以及 LPI2C1,但是这个 FRDM-MCXW71 开发板只引出了一个 LPI2C1。

Image

在 Zephyr RTOS 中,配置开发板上的外设资源,需要在设备树或者 overlay 中配置并使能。在 zephyr_rtos/boards/nxp/frdm_mcxw71/frdm_mcxw71.dts 设备树中关于 lpi2c1 的设定如下:

  • status="okay" 表示启用该I2C控制器;

  • pinctrl-0="\&pinmux_lpi2c1" 表示该I2C控制器使用的引脚复用配置,选用 pinmux_lpi2c1 那一组;

  • pinctrl-names="default" 为上面的 pinctrl-0 状态命名,"default" 表示这是默认引脚配置状态,系统启动时自动应用;

  • accelerometer 和子节点表示在该I2C总线下定义了一个子设备节点, accelerometer 是标签名,@19 是该设备的I2C从机地址。

Image

新建 frdm_mcxw71.overlay

在工程新建 boards/frdm_mcxw71.overlay 文件,这是一个 Devicetree Overlay (设备树覆盖层)文件。 Zephyr 构建系统会将此文件与板级基础DTS (frdm_mcxw71.dts) 合并,用于追加或者覆盖硬件配置。 Overlay 文件是应用层定制硬件配置的标准方式,无需修改 SDK 中的原始板级文件。

重点介绍 overlay 中和 i2c 相关的代码。

  • aliases 节点下有一个 i2c-0=\&lpi2c1 是将 i2c-0 别名指向lpi2c1控制器,应用代码可以通过 DT_ALIAS(i2c_0) 获取 I2C 总线设备,方便跨板移植;

  • \&lpi2c1 节点,是应用 lpi2c1 而不是重新定义;

  • status="okay" 表示启用该i2c总线;

  • clock-frequency=\<400000> 设置I2C时钟频率为 400KHz;

  • 子节点 sen66@6b 表示I2C从设备节点,@6b 表示7位I2C地址为 0x6B;

  • compatible = "sensirion,sen66" 声明设备为 Sensirion SEN66 环境传感器

  • reg = \<0x6b> 表示 I2C 从机地址为 0x6B,必须和上面的一致;

  • status = "okay" 表示启用该传感器;

  • oled: ssd1306@3c 是一个 OLED 显示屏节点,标签为oled,I2C地址为0x3C;其他属性就不一一介绍了。

/* frdm_mcxw71.overlay */

/ {
        aliases {
                led0 = &green_led;
                i2c-0 = &lpi2c1;
        };

        leds {
                compatible = "gpio-leds";

                green_led: led_green {
                        label = "LED_GREEN";
                        gpios = <&gpioa 19 GPIO_ACTIVE_LOW>;
                        status = "okay";
                };
        };
};

&gpioa {
        status = "okay";
};

&hci {
        status = "okay";
};

&nbu {
        status = "okay";
};

/* 引用 lpi2c1 节点进行修改 */
&lpi2c1 {
        status = "okay";
        clock-frequency = <400000>;

        sen66@6b {
                compatible = "sensirion,sen66";
                reg = <0x6b>;
                status = "okay";
        };

        /* SSD1306 OLED 显示屏,分辨率 128x64 */
        oled: ssd1306@3c {
                compatible = "solomon,ssd1306";
                reg = <0x3c>;
                width = <128>;
                height = <64>;
                segment-offset = <0>;
                page-offset = <0>;
                display-offset = <0>;
                multiplex-ratio = <63>;
                segment-remap;
                com-invdir;
                prechargep = <2>;
                status = "okay";
        };
};

另外,还必须在项目配置文件 prj.conf 中使能 I2C 以及 OLED 相关的 CONFIG_XXX,如下图所示。

Image

SEN66 驱动移植

SEN66 驱动代码参考官方SDK,直接拷贝到这个工程中,如下所示, sen66_i2c 就是官方SDK,移植只需要把 sen66_i2c/sample-implementations/zephyr_user_space/sensirion_i2c_hal.c 中的几个函数实现即可,即实现 I2C 底层初始化、收发字节即可。

如下图, i2c_dev = DEVICE_DT_GET(DT_ALIAS(i2c_0)) 就是通过别名访问 lpi2c1 总线。

Image

具体来说就是实现

  • sensirion_i2c_hal_read() ,调用 zephyr API: i2c_read() 读取字节

  • sensirion_i2c_hal_write(),调用 zephyr API: i2c_write() 写入字节

Image

SEN66 线程

在 sen66_thread.c 中新建一个线程,它的流程如下:

  • I2C HAL初始化,SEN66 驱动初始化,设备复位

  • 读取并打印序列号

  • 启动传感器的连续测量模式

  • 每秒读取一次数据,每10行打印一次表头

  • 关键点:i2c_bus_lock()/i2c_bus_unlock() 保护I2C总线访问;

Image

关键代码如下

/**
 * SEN66 线程入口函数
 */
void sen66_thread_entry(void *p1, void *p2, void *p3)
{
        int16_t error = NO_ERROR;

        /* 1. 初始化 I2C HAL 层 */
        sensirion_i2c_hal_init();

        /* 2. 初始化 SEN66 驱动 */
        sen66_init(SEN66_I2C_ADDR_6B);

        /* 3. 设备复位 */
        error = sen66_device_reset();
        if (error != NO_ERROR) {
                LOG_ERR("sen66 device reset error: %i", error);
                return;
        }

        /* 复位后需要等待一段时间(1.2秒) */
        sensirion_hal_sleep_us(1200000);

        /* 4. 获取并打印序列号 */
        int8_t serial_number[32] = {0};
        error = sen66_get_serial_number(serial_number, 32);
        if (error != NO_ERROR) {
                LOG_ERR("failed to get serial number: %i", error);
        } else {
                LOG_INF("SEN66 SN: %s", serial_number);
        }

        /* 5. 启动持续测量 */
        error = sen66_start_continuous_measurement();
        if (error != NO_ERROR) {
                LOG_ERR("执行 start_continuous_measurement() 出错: %i", error);
                return;
        }

        /* 数据变量 */
        uint16_t pm1p0 = 0;
        uint16_t pm2p5 = 0;
        uint16_t pm4p0 = 0;
        uint16_t pm10p0 = 0;
        int16_t humidity = 0;
        int16_t temperature = 0;
        int16_t voc_index = 0;
        int16_t nox_index = 0;
        uint16_t co2 = 0;

        /* 行计数器 */
        uint16_t row_count = 0;

        LOG_INF("SEN66 starts measuring...");

        /* 初始化传感器数据模块 */
        sensor_data_init();

        /* 历史数据计数器 (每分钟添加一次) */
        uint16_t history_counter = 0;

        while (1) {
                /* 获取 I2C 总线锁,保护 SEN66 整个 write+sleep+read 过程 */
                i2c_bus_lock();

                /* 6. 读取测量值 */
                error = sen66_read_measured_values_as_integers(&pm1p0, &pm2p5, &pm4p0, &pm10p0, &humidity, &temperature,
                                                                                                           &voc_index, &nox_index, &co2);

                /* 释放 I2C 总线锁 */
                i2c_bus_unlock();

                if (error != NO_ERROR) {
                        LOG_WRN("Faild to read measurements: %i", error);
                        continue;
                }


                /* 每隔10行打印一次表头 */
                if (row_count % 10 == 0) {
                        /* 使用固定宽度打印表头,注意这里去掉了部分空格,完全靠宽度控制 */
                        LOG_INF("----------------------------------------------------------------"
                                        "----------------------");
                        LOG_INF("%-" COL_W "s %-" COL_W "s %-" COL_W "s %-" COL_W "s %-" COL_W "s %-" COL_W "s %-" COL_W
                                        "s %-" COL_W "s %-" COL_W "s",
                                        "PM1.0", "PM2.5", "PM4.0", "PM10", "Humi(%)", "Temp(℃)", "CO2", "VOC", "NOx");
                }

                /* 7. 输出测量结果 */
                /* * 1. 统一使用 %-8 宽度
                 * 2. 浮点数限制宽度为 8.1f (总宽8,含1位小数)
                 * 3. 整数使用 %-8u 或 %-8i
                 */
                LOG_INF("%-" COL_W ".1f %-" COL_W ".1f %-" COL_W ".1f %-" COL_W ".1f %-" COL_W ".1f %-" COL_W ".1f %-" COL_W
                                "u %-" COL_W ".1f %-" COL_W ".1f",
                                (double)((float)pm1p0 / 10.0f), (double)((float)pm2p5 / 10.0f), (double)((float)pm4p0 / 10.0f),
                                (double)((float)pm10p0 / 10.0f), (double)((float)humidity / 100.0f),
                                (double)((float)temperature / 200.0f), co2, (double)((float)voc_index / 10.0f),
                                (double)((float)nox_index / 10.0f));

                row_count++;

                k_msleep(1000);
        }

        /* 理论上不会到达这里,但保留停止测量的逻辑 */
        sen66_stop_measurement();
}

/* 定义并启动线程 */
K_THREAD_DEFINE(sen66_thread_id, SEN66_THREAD_STACK_SIZE, sen66_thread_entry, NULL, NULL, NULL, SEN66_THREAD_PRIORITY, 0, 0);

OLED驱动

在 src/oled.c 中实现 OLED 驱动,只负责I2C通信,绘制点、线、圆、矩形等基本元素,UI层负责应用层要显示的具体界面。

函数 oled_init() 通过 i2c_dev = DEVICE_DT_GET(DT_ALIAS(i2c_0)) 获取 i2c 句柄。调用 oled_dev = DEVICE_DT_GET(DT_NODELABEL(oled)) 获取 OLED 显示句柄,后续通过这个句柄访问OLED。

Image

UI 线程

主要流程如下:

  • 初始化,OLED驱动初始化

  • 欢迎界面,显示欢迎信息

  • 数据获取,读取传感器数据

  • 数据显示,9种传感器数据,每页显示3个,每隔5秒钟自动翻页显示

  • 异常处理,数据无效时显示等待画面

Image

关键代码如下

/**
 * @file user_ui.c
 * @brief 用户界面线程 - 应用层绘制
 *
 * 负责从传感器获取数据并调用OLED驱动显示
 */

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <stdio.h>

#include "sensor_data.h"
#include "oled.h"
#include "user_ui.h"

LOG_MODULE_REGISTER(user_ui, LOG_LEVEL_INF);

/* UI 线程配置 */
#define UI_THREAD_STACK_SIZE 2048
#define UI_THREAD_PRIORITY 7
#define UI_UPDATE_INTERVAL_MS 2000

/**
 * @brief 显示传感器数据页面1
 */
static void ui_show_page1(const struct sensor_data *data)
{
    char buf[32];

    snprintf(buf, sizeof(buf), "TEMP : %5.1F ^C", (double)data->temperature / 200.0);
    oled_draw_string(0, 0, buf);

    snprintf(buf, sizeof(buf), "HUMI : %5.1F %%", (double)data->humidity / 100.0);
    oled_draw_string(0, 16, buf);

    snprintf(buf, sizeof(buf), "CO2  : %5u PPM", data->co2);
    oled_draw_string(0, 32, buf);
}

/**
 * @brief 显示传感器数据页面2
 */
static void ui_show_page2(const struct sensor_data *data)
{
    char buf[32];

    snprintf(buf, sizeof(buf), "PM1.0: %5.1F UG/M3", (double)data->pm1_0 / 10.0);
    oled_draw_string(0, 0, buf);

    snprintf(buf, sizeof(buf), "PM2.5: %5.1F UG/M3", (double)data->pm2_5 / 10.0);
    oled_draw_string(0, 16, buf);

    snprintf(buf, sizeof(buf), "PM4.0: %5.1F UG/M3", (double)data->pm4_0 / 10.0);
    oled_draw_string(0, 32, buf);
}

/**
 * @brief 显示传感器数据页面3
 */
static void ui_show_page3(const struct sensor_data *data)
{
    char buf[32];

    snprintf(buf, sizeof(buf), "PM10 : %5.1F UG/M3", (double)data->pm10 / 10.0);
    oled_draw_string(0, 0, buf);

    snprintf(buf, sizeof(buf), "VOC  : %5.1F PPB", (double)data->voc_index / 10.0);
    oled_draw_string(0, 16, buf);

    snprintf(buf, sizeof(buf), "NOX  : %5.1F PPB", (double)data->nox_index / 10.0);
    oled_draw_string(0, 32, buf);
}

/**
 * @brief 显示传感器数据(自动翻页)
 */
static void ui_update_display(const struct sensor_data *data)
{
    static uint8_t page_idx = 0;
    static int64_t last_page_switch = 0;
    int64_t now = k_uptime_get();
    char buf[16];

    /* 每5秒切换显示页面 */
    if (now - last_page_switch >= 5000) {
        page_idx = (page_idx % 3) + 1;
        last_page_switch = now;
    }

    oled_clear();

    if (page_idx == 1) {
        ui_show_page1(data);
    } else if (page_idx == 2) {
        ui_show_page2(data);
    } else if (page_idx == 3) {
        ui_show_page3(data);
    }

    /* 页面指示器 */
    snprintf(buf, sizeof(buf), "%d/3 PAGE", page_idx);
    oled_draw_string(64, 48, buf);

    oled_refresh();
}

/**
 * @brief 显示欢迎画面
 */
static void ui_show_welcome(void)
{
    oled_clear();
    oled_draw_centered(0, "EEPW & ELE14");
    oled_draw_centered(16, "MCXW71 BLE HT");
    oled_draw_centered(32, "OLED && BLE");
    oled_draw_centered(48, "WECHAT MINIPROGRAM");
    oled_refresh();
}

/**
 * @brief 显示等待数据画面
 */
static void ui_show_waiting(void)
{
    oled_clear();
    oled_draw_centered(16, "WAITING DATA...");
    oled_refresh();
}

/**
 * @brief UI线程入口函数
 */
void user_ui_thread_entry(void *p1, void *p2, void *p3)
{
    int ret;
    struct sensor_data data;

    LOG_INF("UI thread started");

    /* 初始化OLED驱动 */
    ret = oled_init();
    if (ret != 0) {
        LOG_ERR("OLED init failed: %d", ret);
        return;
    }

    /* 显示欢迎画面 */
    ui_show_welcome();
    k_sleep(K_MSEC(5000));

    /* 主循环 */
    while (1) {
        ret = sensor_data_get(&data);
        if (ret == 0 && data.valid) {
            ui_update_display(&data);
        } else {
            ui_show_waiting();
        }
        k_sleep(K_MSEC(UI_UPDATE_INTERVAL_MS));
    }
}

/* 定义UI线程 */
K_THREAD_DEFINE(user_ui_thread_id, UI_THREAD_STACK_SIZE,
                user_ui_thread_entry, NULL, NULL, NULL,
                UI_THREAD_PRIORITY, 0, 0);

运行演示

  • 上电后OLED上显示欢迎界面,等待5秒钟;

  • 等待SEN66获取数据,在UI上显示,分3个页面,每个页面显示5秒钟,然后切换到下一个页面;

  • 三个页面轮播;


VID_20260610_194900Part001.gif


问题与解决

问题1: hci_core.c 504 Controller unresponsive

Image

问题

解决办法,参考 zephyr 官网 https://docs\.zephyrproject\.org/latest/boards/nxp/frdm\_mcxw71/doc/index\.html 这里有针对 FRDM-MCXW71 开发板的资源介绍、

Image

问题1:解决,获取无线固件并烧写

为支持蓝牙功能, frdm_mcxw71 需要获取二进制固件blob,即运行命令行 west blobs fetch hal_nxp 进行下载。

Image

命令行烧写 NBU 固件

Image

烧写成功

Image

问题2:烧写 NBU 固件之后的运行错误

报错如下,还是 hci_core.c:504 Controller unresponsive. command opcode 0x0c03 timeout with err -11

可能的原因:配置文件中缺少 MCXW71 BLE HCI 控制器的驱动配置

Image

问题2:解决,修改 prj.conf 和 overlay 文件

修改点1:prj.conf 新增 BLE HCI IPC 控制器配置

Image

修改点2: 更新 frdm_mcxw71.overlay 添加 BLE HCI 和 NBU 设备节点并启用

Image

问题3:OLED device not ready

Image

问题3:解决,修改 overlay 文件

修改overlay文件,即 boards/frdm_mcxw71.overlay 文件,在 lpi2c1 节点下新增 oled 标签,设置 ssd1306 设备属性,兼容性为 solomon,ssd1306fb;宽度、高度等属性,如下所示:

Image

问题4:运行一段时间后传感器数据异常

如下图所示,SEN66传感器只有一两次数据正常,其他读数都是异常的。

Image

经过分析,异常的数据都是当前数据类型的最大值,例如

温度 32760 ≈ 32767(INT16_MAX),PM 65335 ≈ 65535(UINT16_MAX)。这些都是 SEN66 传感器返回的无效/错误标记值。

由于 sen66 是通过I2C通信,挂载 i2c0,并且 oled 也是挂载 i2c0 上,并且两个线程的优先级相近,可能导致 sen66_thread.c 现成在读取传感器数据时被打断。

问题4:解决,给 i2c0 访问添加互斥锁

第一步:添加 i2c_bus_clock.c/h

实现3个API,即针对 i2c 的 mutex 初始化、上锁、解锁。

Image

第二步:互斥锁初始化,针对 i2c0 访问上锁、解锁

  • 在 main.c 中调用 i2c_bus_lock_init() 初始化互斥锁;

  • 在 sen66_thread.c 中读取SEN66传感器的函数前后上锁、解锁;

  • 在 oled.c 中刷新 OLED 屏幕上锁、解锁;

Image

Image

Image

解决之后运行50分钟再没有出现数值为最大值的异常情况,如下日志所示:

[00:50:35.643,035] <inf> sen66_thread: --------------------------------------------------------------------------------------
[00:50:35.643,127] <inf> sen66_thread: PM1.0    PM2.5    PM4.0    PM10     Humi(%)  Temp(℃) CO2      VOC      NOx
[00:50:35.643,157] <inf> sen66_thread: 497.7    518.3    518.3    518.3    49.3     26.2     787      126.0    1.0
[00:50:36.676,269] <inf> sen66_thread: 746.4    777.2    777.2    777.2    49.3     26.2     787      125.0    1.0
[00:50:37.709,442] <inf> sen66_thread: 717.4    747.0    747.0    747.0    49.4     26.2     787      126.0    1.0
[00:50:38.743,621] <inf> sen66_thread: 593.9    618.4    618.4    618.4    49.4     26.2     787      126.0    1.0
[00:50:39.777,801] <inf> sen66_thread: 456.3    475.2    475.2    475.2    49.4     26.2     787      126.0    1.0
[00:50:40.812,011] <inf> sen66_thread: 516.6    537.9    537.9    537.9    49.4     26.2     787      129.0    1.0
[00:50:41.846,160] <inf> sen66_thread: 689.5    718.0    718.0    718.0    49.4     26.2     787      129.0    1.0
[00:50:42.880,371] <inf> sen66_thread: 642.4    668.9    668.9    668.9    49.4     26.2     787      129.0    1.0
[00:50:43.913,543] <inf> sen66_thread: 522.7    544.2    544.2    544.2    49.4     26.2     787      129.0    1.0
[00:50:44.947,753] <inf> sen66_thread: 396.0    412.3    412.3    412.3    49.4     26.2     787      137.0    1.0
[00:50:45.981,903] <inf> sen66_thread: --------------------------------------------------------------------------------------
[00:50:45.981,994] <inf> sen66_thread: PM1.0    PM2.5    PM4.0    PM10     Humi(%)  Temp(℃) CO2      VOC      NOx
[00:50:45.982,025] <inf> sen66_thread: 579.5    603.4    603.4    603.4    49.4     26.2     786      136.0    1.0
[00:50:47.015,136] <inf> sen66_thread: 724.5    754.4    754.4    754.4    49.4     26.2     786      135.0    1.0
[00:50:48.049,285] <inf> sen66_thread: 661.7    689.0    689.0    689.0    49.4     26.2     785      135.0    1.0
[00:50:49.083,465] <inf> sen66_thread: 533.3    555.4    555.4    555.4    49.4     26.2     785      135.0    1.0
[00:50:50.116,668] <inf> sen66_thread: 401.7    418.3    418.3    418.3    49.4     26.2     785      134.0    1.0
[00:50:51.150,848] <inf> sen66_thread: 653.1    680.0    680.0    680.0    49.4     26.2     784      134.0    1.0
[00:50:52.185,058] <inf> sen66_thread: 701.4    730.4    730.4    730.4    49.4     26.2     784      134.0    1.0
[00:50:53.231,903] <inf> sen66_thread: 606.6    631.6    631.6    631.6    49.4     26.2     784      134.0    1.0
[00:50:54.266,113] <inf> sen66_thread: 477.2    496.9    496.9    496.9    49.4     26.2     784      134.0    1.0
[00:50:55.299,285] <inf> sen66_thread: 426.8    444.5    444.5    444.5    49.4     26.2     784      134.0    1.0
[00:50:56.333,465] <inf> sen66_thread: --------------------------------------------------------------------------------------
[00:50:56.333,557] <inf> sen66_thread: PM1.0    PM2.5    PM4.0    PM10     Humi(%)  Temp(℃) CO2      VOC      NOx
[00:50:56.333,587] <inf> sen66_thread: 758.6    789.9    789.9    789.9    49.4     26.2     784      134.0    1.0
[00:50:57.366,699] <inf> sen66_thread: 756.7    787.9    787.9    787.9    49.4     26.2     784      134.0    1.0
[00:50:58.400,848] <inf> sen66_thread: 635.8    662.0    662.0    662.0    49.4     26.2     785      134.0    1.0
[00:50:59.468,231] <inf> sen66_thread: 490.6    510.9    510.9    510.9    49.4     26.2     785      134.0    1.0
[00:51:00.502,441] <inf> sen66_thread: 493.0    513.3    513.3    513.3    49.4     26.2     786      134.0    1.0
[00:51:01.536,621] <inf> sen66_thread: 693.6    722.2    722.2    722.2    49.4     26.2     786      134.0    1.0
[00:51:02.570,770] <inf> sen66_thread: 572.2    595.8    595.8    595.8    49.4     26.2     786      134.0    1.0
[00:51:03.604,980] <inf> sen66_thread: 438.7    456.8    456.8    456.8    49.4     26.2     786      134.0    1.0
[00:51:04.638,153] <inf> sen66_thread: 565.2    588.6    588.6    588.6    49.4     26.2     785      134.0    1.0
[00:51:05.672,332] <inf> sen66_thread: 723.1    753.0    753.0    753.0    49.4     26.2     785      134.0    1.0





关键词: FRDM-MCXW71     OLED     SEN66         

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]