尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

基于STM32与MQ-2的烟雾浓度监测报警系统设计与实现

基于STM32与MQ-2的烟雾浓度监测报警系统设计与实现
📅 发布时间:2026/7/30 6:43:58

1. 项目概述:一个实用的烟雾浓度监测报警系统

最近在工作室整理电子物料,翻出来几个MQ-2烟雾传感器模块,想着不能浪费,正好手头有STM32的开发板和OLED屏幕,就顺手搭了一个烟雾浓度监测报警系统。这个项目虽然听起来简单,但麻雀虽小五脏俱全,它集成了传感器数据采集、本地显示、声光报警以及数据上传到电脑端分析的功能,非常适合作为学习STM32外设驱动、ADC采样、I2C通信以及串口应用的综合练手项目。无论你是刚接触STM32的新手,想通过一个完整项目串联知识点,还是有一定经验的开发者,想快速搭建一个环境监测原型,这套方案都能给你提供清晰的思路和可直接复用的代码。

整个系统的核心逻辑很直观:STM32单片机作为大脑,持续读取MQ-2传感器输出的模拟电压值,这个电压值对应着环境中烟雾或可燃气体的浓度。单片机一方面将处理后的浓度值实时显示在小小的OLED屏幕上,让你能直观看到当前环境状况;另一方面,通过串口将浓度数据打包发送到电脑的串口调试助手,方便你记录数据或进行进一步分析。当浓度超过你设定的安全阈值时,单片机还会驱动蜂鸣器发出警报,实现本地预警。下面,我就把这个项目的设计思路、硬件连接、代码实现以及调试过程中踩过的坑,毫无保留地分享出来。

2. 系统整体设计与核心思路拆解

2.1 核心需求与功能定义

这个项目的目标很明确,就是构建一个实时、本地可视、可远程监控的烟雾浓度监测终端。拆解开来,它需要完成以下四个核心功能:

  1. 数据采集:准确、稳定地读取MQ-2传感器的模拟信号。
  2. 本地显示:将浓度信息以清晰易懂的方式呈现在OLED屏幕上。
  3. 阈值报警:在浓度超标时,通过蜂鸣器发出明确的声学警告。
  4. 数据通信:将浓度数据通过串口发送至上位机(电脑),实现数据导出和远程监控的可能性。

2.2 硬件选型与方案考量

为什么选择这些器件?这背后有成本和实用性的权衡。

  • 主控MCU:STM32F103C8T6(核心板)。这是STM32家族中经久不衰的“蓝色药丸”核心板,性价比极高。它拥有足够多的GPIO、多路ADC、USART和I2C接口,完全满足本项目需求。对于初学者来说,其社区资源(教程、库函数)也最为丰富,降低了学习门槛。
  • 传感器:MQ-2烟雾/可燃气体传感器模块。MQ-2是一个广谱传感器,对液化气、丙烷、氢气、烟雾等都很敏感。选择模块而非裸传感器,是因为模块通常集成了比较器电路,提供了数字量(DO)和模拟量(AO)两种输出。我们使用AO模拟输出,可以获得连续的浓度信息,而不仅仅是“有”或“无”的开关量,数据更有价值。
  • 显示器件:0.96寸OLED屏幕(SSD1306驱动,I2C接口)。OLED屏幕自发光、对比度高、功耗低,在少量信息显示的场景下比LCD更具优势。选择I2C接口版本(通常只有4根线:VCC, GND, SCL, SDA),可以极大节省MCU的IO口,接线也简洁。SPI接口的OLED虽然刷新更快,但本项目对刷新率要求不高,I2C足矣。
  • 报警器件:有源蜂鸣器。有源蜂鸣器内部集成了振荡电路,通电即响,驱动简单(一个GPIO口控制高低电平即可),声音响亮,非常适合做报警提示。无源蜂鸣器需要MCU产生PWM波驱动才能发声,虽然音调可控,但本项目只需要简单的“嘀嘀”报警声,有源蜂鸣器是更经济高效的选择。
  • 通信接口:USB转TTL串口模块。这是连接STM32与电脑的桥梁。STM32的USART引脚输出的是TTL电平,需要通过这个模块转换为USB信号,电脑才能识别。同时,它也为STM32核心板提供供电和程序烧录(通过串口方式)的功能,一举两得。

2.3 软件架构与流程规划

软件层面,我们采用前后台(超级循环)架构,这对于功能明确、实时性要求不极端的中小型项目来说,结构清晰且易于理解。主程序在一个while(1)大循环中不断执行以下任务:

  1. 定时(例如每500ms)启动一次ADC转换,读取MQ-2的电压值。
  2. 将ADC原始值转换为电压,再根据传感器特性(需校准)映射为相对的“浓度值”。
  3. 刷新OLED屏幕,显示当前浓度值和报警阈值。
  4. 判断当前浓度是否超过阈值,若超过,则控制蜂鸣器鸣叫;否则关闭蜂鸣器。
  5. 将浓度数据格式化为字符串(例如"Smoke: 256 ppm\r\n"),通过串口发送出去。

这里的关键在于定时采样。我们不能在循环里不停地采样ADC,那会浪费CPU资源且可能使串口发送数据不流畅。通常采用延时函数或者定时器中断来产生固定的采样周期。为了代码结构更好,我推荐使用一个简单的定时器,产生一个比如1ms的时基,然后在主循环中判断时间标志位来实现非阻塞的定时任务。

3. 硬件连接与核心电路解析

3.1 模块引脚定义与接线图

工欲善其事,必先利其器。先把各个模块的引脚搞清楚是成功的第一步。

  • STM32F103C8T6核心板:我们需要用到以下引脚:

    • 3.3V和GND:为所有模块供电。特别注意:MQ-2模块的工作电压通常是5V,但其AO模拟输出引脚的最大电压可能也是5V,而STM32的ADC引脚耐受电压一般为3.3V。直接连接可能损坏单片机!稳妥的做法是,MQ-2模块用5V供电,但其AO输出线串联一个1kΩ左右的电阻后再接入STM32的ADC引脚,或者使用电平转换模块。另一种常见方案是,选择AO输出范围在0-3.3V的MQ-2模块(有些模块可跳线选择),或者通过分压电路将5V信号衰减至3.3V以内。本文假设你使用的模块AO输出兼容3.3V电平。
    • PA0:配置为ADC输入通道(ADC1_IN0),连接MQ-2的AO引脚。
    • PB6:配置为I2C1的SCL时钟线,连接OLED的SCL。
    • PB7:配置为I2C1的SDA数据线,连接OLED的SDA。
    • PB8:配置为推挽输出的GPIO,连接蜂鸣器的信号线(正极)。蜂鸣器负极接GND。
    • PA9:配置为USART1的TX发送引脚,连接USB转TTL模块的RX。
    • PA10:配置为USART1的RX接收引脚,连接USB转TTL模块的TX。
    • BOOT0:需要置低(接GND)或通过跳线帽设置为正常启动模式。
    • NRST:复位引脚,通常悬空即可。
  • MQ-2模块:

    • VCC:接5V电源(可从USB转TTL模块或核心板的5V引脚取)。
    • GND:接电源地。
    • AO:模拟输出,接STM32的PA0(需注意电平兼容问题)。
    • DO:数字输出,本项目不用,可悬空。
  • OLED屏幕 (I2C):

    • VCC:接3.3V。
    • GND:接GND。
    • SCL:接STM32的PB6。
    • SDA:接STM32的PB7。
  • 有源蜂鸣器:

    • 标有+或VCC的引脚:接STM32的PB8。
    • 标有-或GND的引脚:接GND。
  • USB转TTL模块:

    • 3.3V或5V:可以为STM32核心板供电(接核心板的3.3V或5V引脚)。建议统一用5V供电,电流更足。
    • GND:接核心板和所有模块的GND,共地至关重要!
    • TX:接STM32的PA10(USART1_RX)。
    • RX:接STM32的PA9(USART1_TX)。

注意:接线时务必断电操作!所有电源连接(VCC, GND)确认无误后再上电。特别是I2C总线,SDA和SCL不要接反。

3.2 电平兼容与ADC参考电压问题

这是硬件连接中最容易出问题的地方,值得单独拿出来讨论。

  1. MQ-2 AO输出电平:市面上多数MQ-2模块在5V供电时,AO引脚在洁净空气中的输出电压约为0.1V-0.3V,在高浓度气体中可能接近5V。STM32的GPIO和ADC引脚通常只能承受3.6V电压。如果直接将5V的AO信号接入PA0,长时间工作或气体浓度高时可能损坏单片机。

    • 解决方案A(推荐):为MQ-2模块提供5V电源,但在AO输出和STM32的ADC引脚之间加入一个简单的电阻分压电路。例如,用一个1kΩ电阻串联一个2kΩ电阻,将AO电压分压至原来的1/3(5V->1.67V),这样就在STM32的安全范围内,且保留了足够的测量精度。
    • 解决方案B:寻找标称AO输出为0-3.3V的MQ-2模块,或者模块上有输出电平选择跳线帽。
    • 解决方案C:使用专用的电平转换芯片(如TXS0108E)或模块。
  2. STM32的ADC参考电压:STM32F103C8T6的ADC参考电压默认接在VDDA引脚上,而VDDA通常与VCC(3.3V)相连。这意味着ADC测量的电压范围是0~3.3V。如果你的VCC不稳定,ADC测量值也会漂移。对于精度要求稍高的场合,建议确保给核心板供电的3.3V电源纹波小、较稳定。

4. 软件实现与核心代码解析

4.1 开发环境与工程配置

我使用的是Keil MDK(ARMCC编译器)和STM32标准外设库(StdPeriph_Lib)。使用HAL库或LL库同样可以,原理相通。首先,我们需要在工程中正确配置以下外设:

  1. ADC1:选择通道0(对应PA0),配置为独立模式、连续扫描禁用、使能连续转换。采样时间可以设置长一些(例如239.5个周期),以提高抗干扰能力。需要开启DMA吗?对于单通道、低速采样的本项目,不需要。我们采用查询方式或者中断方式读取一次转换结果即可。
  2. I2C1:配置为标准模式(100kHz),时钟延展使能。注意GPIO模式要设置为开漏输出(Open-Drain),并启用内部上拉电阻(或者外部接上拉电阻到3.3V),这是I2C总线标准所要求的。
  3. USART1:配置为异步模式,波特率115200(与串口调试助手匹配),8位数据位,无校验,1位停止位。需要开启发送中断或使用查询方式发送。
  4. GPIO:PB8配置为推挽输出,用于控制蜂鸣器。
  5. SysTick定时器:用于产生精确的毫秒级延时,方便我们实现非阻塞的定时任务。

4.2 ADC采样与数据处理

ADC是感知世界的“眼睛”,其稳定性和准确性直接决定系统性能。

// 假设已初始化ADC1,通道0, 12位分辨率 uint16_t ADC_GetValue(void) { ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 启动转换 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // 等待转换结束 return ADC_GetConversionValue(ADC1); // 读取转换值 } float ADC_ConvertToVoltage(uint16_t adc_value) { // Vref = 3.3V, 12位ADC最大值是4095 return (adc_value * 3.3f) / 4095.0f; }

读取到电压值后,如何把它变成有意义的“浓度”呢?MQ-2的灵敏度特性曲线(Rs/Ro vs. 气体浓度)通常在其数据手册里。但对我们这个定性或半定量应用来说,可以进行简化校准:

  1. 确定Ro(洁净空气中的传感器电阻):将传感器在洁净空气中预热至少24小时(这是关键!MQ-2需要预热才能稳定)。然后测量此时的输出电压Vc。根据模块原理图(通常AO输出与Rs分压),可以反推出此时的Rs,这个Rs近似等于Ro。对于很多模块,我们可以直接记录下此时的ADC原始值ADC_air作为“空气基准”。
  2. 计算浓度比值:定义ratio = (float)ADC_value / (float)ADC_air。这个比值越大,说明气体浓度越高。你可以通过实验,在已知浓度的烟雾源(需谨慎安全操作!)附近测试,记录下不同浓度对应的ratio值,建立一个简单的查找表或线性关系。
  3. 本项目简化处理:由于精确校准需要专业环境和气室,对于报警应用,我们可以采用更简单的办法:直接使用ADC原始值或电压值作为“浓度指示值”。然后设置一个经验阈值,当这个值超过阈值就报警。这个阈值需要通过实验来确定:在安全环境下,产生少量烟雾,观察数值变化,找到一个能可靠触发报警但又不会误报的值。

4.3 OLED显示驱动与界面设计

OLED显示我们使用现成的驱动库,如ssd1306.h或OLED_Font.h。核心是初始化I2C和调用显示函数。

// 初始化I2C后,初始化OLED OLED_Init(); OLED_Clear(); // 在主循环中刷新显示 void OLED_RefreshDisplay(uint16_t smoke_value, uint16_t threshold) { char str_buf[20]; OLED_ShowString(0, 0, "Smoke Monitor", 16); OLED_ShowString(0, 2, "Value:", 16); sprintf(str_buf, "%4d", smoke_value); OLED_ShowString(48, 2, str_buf, 16); OLED_ShowString(0, 4, "Thresh:", 16); sprintf(str_buf, "%4d", threshold); OLED_ShowString(56, 4, str_buf, 16); // 如果浓度超标,显示警告标志 if(smoke_value > threshold) { OLED_ShowString(90, 2, "!!!", 16); } else { OLED_ShowString(90, 2, " ", 16); // 清除警告 } }

显示界面力求简洁明了:第一行显示标题,第二行显示当前浓度值,第四行显示报警阈值,并在浓度超标时在数值旁显示“!!!”警示。注意OLED屏幕的坐标体系(x, y)和字体大小(这里用了16x8的字体),需要根据你的驱动库函数进行调整。

4.4 串口数据发送与格式化

串口是将数据发送到电脑的“嘴巴”,格式清晰很重要。

// 初始化USART1,波特率115200 void USART1_SendString(char *str) { while(*str) { while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // 等待发送缓冲区空 USART_SendData(USART1, *str++); } } // 在主循环中,定时(如每秒)发送一次数据 if(send_uart_flag) { // 这个标志位由定时器置位 send_uart_flag = 0; char uart_buf[64]; // 格式化为: "Smoke: 345, Voltage: 0.85V, Status: OK/ALARM\r\n" if(smoke_value > threshold) { sprintf(uart_buf, "Smoke: %4d, Voltage: %.2fV, Status: ALARM\r\n", smoke_value, voltage); } else { sprintf(uart_buf, "Smoke: %4d, Voltage: %.2fV, Status: OK\r\n", smoke_value, voltage); } USART1_SendString(uart_buf); }

发送的数据格式包含了原始值、电压值和状态,用逗号分隔,便于电脑端软件(如串口调试助手、Python脚本、Excel)解析。末尾的\r\n是换行符,确保每次发送的数据在接收端独立成行。

4.5 主程序逻辑与状态管理

将所有模块整合起来的主循环,其结构体现了系统的实时性和响应性。

int main(void) { // 系统时钟、外设初始化 SystemInit(); GPIO_Init(); ADC1_Init(); I2C1_Init(); OLED_Init(); USART1_Init(115200); SysTick_Init(); // 初始化系统滴答定时器,用于产生1ms中断 TIM3_Init(); // 初始化一个定时器,用于产生500ms的采样周期标志位 uint16_t adc_value = 0; uint16_t smoke_value = 0; uint16_t alarm_threshold = 1500; // 示例阈值,需根据实测调整 uint8_t alarm_on = 0; OLED_Clear(); OLED_ShowString(0, 0, "System Ready", 16); Delay_ms(1000); while(1) { // 任务1:定时采样ADC if(adc_sample_flag) { // 由TIM3中断置位 adc_sample_flag = 0; adc_value = ADC_GetValue(); // 可选:进行软件滤波,如滑动平均滤波 smoke_value = adc_value; // 这里直接用ADC值代表浓度 } // 任务2:刷新OLED显示 OLED_RefreshDisplay(smoke_value, alarm_threshold); // 任务3:报警判断与控制 if(smoke_value > alarm_threshold) { if(!alarm_on) { BEEP_ON(); // 宏定义,置PB8为高电平 alarm_on = 1; } } else { if(alarm_on) { BEEP_OFF(); // 宏定义,置PB8为低电平 alarm_on = 0; } } // 任务4:定时发送串口数据 if(uart_send_flag) { // 由另一个定时器或计数置位 uart_send_flag = 0; Send_Smoke_Data_UART(smoke_value, alarm_threshold); } // 其他任务... 如按键扫描调整阈值(如果接了按键) // Key_Scan(); } }

这个主循环清晰展示了基于标志位的协作式调度。每个任务(采样、显示、报警、通信)都由对应的标志位触发,而这些标志位在定时器中断服务函数中被设置。这样保证了每个任务都能以固定的周期执行,避免了使用Delay函数导致的CPU空转和响应迟钝。

5. 调试技巧与常见问题实录

5.1 上电无反应或OLED不显示

  • 问题现象:连接好电路上电后,OLED屏幕没有任何显示,或者STM32芯片发热。
  • 排查思路:
    1. 电源检查:首先用万用表测量STM32核心板的3.3V和GND之间电压是否为3.3V左右。测量OLED的VCC引脚是否有3.3V。如果电压为0或很低,检查USB线、USB转TTL模块的供电能力,或者是否有短路。
    2. 接线复查:这是最高频的错误来源。逐根线核对,特别是I2C的SDA和SCL是否接反,OLED和STM32的I2C引脚是否对应(PB6/PB7或PB8/PB9)。蜂鸣器正负极是否接反。
    3. 程序下载:确认程序是否成功烧录到单片机。可以写一个最简单的LED闪烁程序测试一下核心板是否工作正常。
    4. OLED初始化:确认OLED驱动代码中的I2C地址是否正确(通常0x78或0x7A)。尝试在初始化后调用清屏和显示测试字符的函数,并检查这些函数是否被成功执行。

5.2 ADC读数不稳定或始终为0

  • 问题现象:串口打印的烟雾浓度值乱跳,或者一直为0/4095。
  • 排查思路:
    1. 电平兼容再确认:这是ADC问题的首要怀疑对象。用万用表测量MQ-2模块AO引脚对GND的电压。在洁净空气中,电压应该是一个较低的值(如0.1-0.5V)。如果接近5V或0V,检查传感器是否预热、是否损坏。确保这个电压不超过3.3V!
    2. ADC引脚配置:确认STM32的PA0引脚配置为模拟输入模式(GPIO_Mode_AIN),而不是浮空输入或推挽输出。
    3. 参考电压:测量STM32的VDDA引脚(通常与3.3V相连)电压是否稳定。
    4. 软件滤波:ADC读数存在固有的噪声。可以在软件中实现滤波算法,如滑动平均滤波:维护一个数组存储最近N次采样值,每次输出这N个值的平均值。这能有效平滑数据。
      #define FILTER_LEN 10 uint16_t adc_filter_buf[FILTER_LEN] = {0}; uint8_t filter_index = 0; uint16_t ADC_Filter(uint16_t new_value) { adc_filter_buf[filter_index] = new_value; filter_index = (filter_index + 1) % FILTER_LEN; uint32_t sum = 0; for(int i=0; i<FILTER_LEN; i++) { sum += adc_filter_buf[i]; } return (uint16_t)(sum / FILTER_LEN); }

5.3 串口调试助手收不到数据或乱码

  • 问题现象:电脑上的串口调试助手打开了对应COM口,但看不到数据,或者看到的是乱码。
  • 排查思路:
    1. 接线检查:TX接RX,RX接TX,这是最容易接反的。确认USB转TTL模块的TX接STM32的PA10(RX),RX接PA9(TX)。
    2. 共地检查:确保USB转TTL模块的GND与STM32核心板的GND连接在一起。没有共地,通信必然失败。
    3. 波特率匹配:检查STM32程序里USART的初始化波特率是否与串口调试助手设置的波特率完全一致(如115200)。
    4. 串口助手设置:数据位8,停止位1,无校验,无流控。换一个串口助手软件(如AccessPort、Putty)试试,有时是软件兼容性问题。
    5. 代码检查:确认USART_SendData函数发送的是单个字符,而USART1_SendString函数正确遍历了字符串。检查发送的字符串末尾是否添加了\r\n。

5.4 蜂鸣器不响或常响

  • 问题现象:浓度超过阈值时蜂鸣器没反应,或者一上电就响。
  • 排查思路:
    1. 驱动能力:STM32的GPIO输出电流有限(通常几mA到20mA)。有源蜂鸣器工作电流可能较大(可达30mA以上)。直接驱动可能导致声音小或单片机复位。解决方案:在GPIO(PB8)和蜂鸣器正极之间加一个NPN三极管(如S8050)或MOSFET(如2N7002)来驱动,用单片机的IO口控制三极管的基极。
    2. 电平逻辑:确认你的代码逻辑。BEEP_ON()是置高电平还是低电平?这取决于你的蜂鸣器模块是高电平触发还是低电平触发。用万用表测量蜂鸣器信号引脚在报警时的电压变化即可知。
    3. 阈值设置:检查你的alarm_threshold值是否合理。如果阈值设得太低,可能一上电就报警;设得太高,则永远不报警。通过串口观察正常的smoke_value范围来调整。

5.5 系统功耗与稳定性优化

这是一个课后思考题。如果你希望这个设备能电池供电长期运行,需要考虑功耗。

  1. 降低采样频率:烟雾浓度变化不会很快,将采样和发送数据的频率从每秒2次降低到每5秒1次。
  2. 使用停机模式:在长时间无报警时,让STM32进入低功耗的停机模式(Stop Mode),仅由外部中断(如传感器数字输出DO变化)或定时器唤醒。
  3. 关闭不必要的外设:在初始化时,只开启需要用到的外设时钟(ADC, I2C, USART, TIM)。在进入低功耗前,关闭OLED屏幕(有专门的命令)、蜂鸣器。
  4. 硬件优化:选择低功耗的LDO稳压器,MQ-2传感器可以间歇性供电(通过一个GPIO控制MOSFET来开关其电源),因为它的预热时间很长,不适合频繁开关。

这个项目从硬件连接到软件调试,涵盖了嵌入式开发中多个基础且重要的环节。当你成功看到OLED上跳动的数值,听到超阈值时蜂鸣器的警报,并在串口助手上看到规整的数据流时,那种成就感是看多少遍教程都无法替代的。希望这份详细的拆解能帮你少走弯路,顺利实现你的烟雾监测系统。代码虽然重要,但调试过程中培养出来的硬件感觉和问题排查思路,才是更宝贵的财富。

相关新闻

  • Prompt Engineering 的未来:从手工设计到自动化优化的趋势判断
  • 设计模式实战:单例与工厂模式深度解析
  • Instagram多账号运营的数据标准化与智能发布策略

最新新闻

  • C#调用Windows API控制光驱托盘:P/Invoke与MCI命令实战
  • 专科生论文降AI率工具测评与实操指南
  • 7月钉飞企AI混战:存量格局难破,谁能让AI为企业真正增收?
  • STM32 G4 ADC高精度采集实战:从硬件过采样到软件滤波全解析
  • PX4与Matlab/Simulink联合仿真:无人机飞控算法开发与验证指南
  • Java 后端转型大模型:Demo 能跑不等于能上线

日新闻

  • 终极TeamSpeak3音乐机器人搭建指南:5分钟实现语音聊天室音频播放
  • 广州海珠区内搬家攻略,平价靠谱搬家服务商推荐,专业打包搬运省心避坑全流程指南 - 厚道搬家
  • 大语言模型入门指南:从零到精通掌握AI核心技术的5大步骤

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号