基于STM32+手机APP设计的智能停车场系统——程序源码&原理图&设计原理&设计文档&演示视频&框图等(文末工程资料下载)

基于STM32+手机APP设计的智能停车场系统

演示视频

基于STM32+手机APP设计的智能停车场系统

元器件:DHT11、MQ2、STM32F103C8T6、SG90舵机、RC522频射模块、HC-SR04超声波模块、OLED、wifi模块、LED灯、蜂鸣器

功能简介
1、进出停车场时需要刷卡,进行一个记时、计费的功能。
2、停车位配有超声波检测,主要识别车位是否被占用。
3、车位区域配有OLED显示屏,用户可以通过显示屏看到空闲车位。
4、车位配有车位灯。当用户找不到车位可以通过手机点亮车位灯
5、停车场配有温湿度检测和烟雾检测模块。当环境发生异常状态。会触动紧急报警。
6、停车场信息会通过Wi-Fi发送数据上传至阿里云。用户可以通过手机了解到停车场空闲车位和停车时间、费用。


摘要

本文详细介绍了一种基于 STM32 的智能停车场管理系统的设计与实现。该系统结合了多种传感器和通信技术,实现了停车场的智能化管理,包括车辆进出计时计费、车位占用检测、空闲车位显示、车位灯控制、环境监测以及数据上传等功能。本文对系统的硬件设计和软件设计进行了深入探讨,阐述了各模块的工作原理和实现细节。

关键词:STM32;智能停车场;传感器;通信技术

一、引言

随着城市化进程的加速,汽车数量不断增加,停车场的管理变得越来越重要。传统的停车场管理方式存在效率低下、人工成本高、信息不透明等问题。为了解决这些问题,智能停车场管理系统应运而生。本文设计的智能停车场管理系统采用了 STM32 微控制器作为核心,结合了多种传感器和通信技术,实现了停车场的智能化管理,提高了停车场的运营效率和用户体验。

二、系统总体设计

(一)系统功能需求

  1. 进出停车场时需要刷卡,进行计时、计费的功能。
  2. 停车位配有超声波检测,识别车位是否被占用。
  3. 车位区域配有 OLED 显示屏,用户可以通过显示屏看到空闲车位。
  4. 车位配有车位灯。当用户找不到车位可以通过手机点亮车位灯。
  5. 停车场配有温湿度检测和烟雾检测模块。当环境发生异常状态,会触动紧急报警。
  6. 停车场信息会通过 Wi-Fi 发送数据上传至阿里云。用户可以通过手机了解到停车场空闲车位和停车时间、费用。

(二)系统总体架构
系统主要由 STM32 最小系统、DHT11 模块、MQ - 2 模块、SG90 舵机、OLED 显示模块、HC - SR04 超声波模块、RC522 频射模块、Wi - Fi 模块、LED 灯、蜂鸣器等组成。STM32 最小系统作为核心控制器,负责协调各模块的工作,实现数据的采集、处理和传输。DHT11 模块用于检测停车场的温湿度,MQ - 2 模块用于检测烟雾浓度,SG90 舵机用于控制停车场的门,OLED 显示模块用于显示停车场的信息,HC - SR04 超声波模块用于检测车位是否被占用,RC522 频射模块用于刷卡识别车辆,Wi - Fi 模块用于将停车场的数据上传至阿里云,LED 灯用于指示车位的状态,蜂鸣器用于报警。

三、硬件设计

(一)STM32 最小系统
STM32 最小系统包括 STM32F103C8T6 芯片、时钟电路、复位电路、电源电路等。STM32F103C8T6 芯片是一款基于 ARM Cortex - M3 内核的微控制器,具有高性能、低功耗、丰富的外设接口等特点。时钟电路为芯片提供时钟信号,复位电路用于系统的复位,电源电路为系统提供稳定的电源。

(二)传感器模块

  1. DHT11 模块
    • DHT11 是一款数字式温湿度传感器,它包括一个电容式感湿元件和一个 NTC 测温元件,并与一个高性能 8 位单片机相连接。
    • 该模块通过 PA4 引脚与 STM32 连接,实现温湿度的检测。STM32 通过单总线协议与 DHT11 进行通信,发送起始信号后,DHT11 会返回温湿度数据。
  2. MQ - 2 模块
    • MQ - 2 是一款半导体烟雾传感器,能够检测空气中的烟雾浓度。
    • 它通过 PB0 引脚与 STM32 连接,将检测到的烟雾浓度模拟信号传输给 STM32 的 ADC(模数转换器),STM32 对模拟信号进行采样和转换,得到数字形式的烟雾浓度数据。
  3. HC - SR04 超声波模块
    • HC - SR04 超声波模块用于检测车位是否被占用,它通过发射超声波并接收反射回来的超声波来测量距离。
    • 该模块通过 PA6 和 PA7 引脚与 STM32 连接,PA6 作为 Trig 引脚,用于发送触发信号,PA7 作为 Echo 引脚,用于接收反射回来的超声波信号。STM32 通过精确计时超声波的发射和接收时间差,根据声速计算出车位与障碍物之间的距离。

(三)执行器模块

  1. SG90 舵机
    • SG90 舵机用于控制停车场的门,通过 PA1 引脚与 STM32 连接。
    • STM32 通过发送 PWM(脉冲宽度调制)信号控制舵机的角度,实现门的开关操作。PWM 信号的占空比决定了舵机的转角位置。
  2. OLED 显示模块
    • OLED 显示模块用于显示停车场的信息,如空闲车位、温湿度、烟雾浓度等。
    • 它通过 PB8 和 PB9 引脚与 STM32 连接,分别作为 SCL(串行时钟线)和 SDA(串行数据线)信号的输入输出引脚。STM32 通过 IIC(集成电路总线)协议与 OLED 显示模块进行通信,发送指令和数据,控制 OLED 显示相应的信息。
  3. LED 灯和蜂鸣器
    • LED 灯用于指示车位的状态,通过 PB5 和 PB6 引脚与 STM32 连接。STM32 可以通过控制这两个引脚的电平高低来点亮或熄灭 LED 灯。
    • 蜂鸣器用于报警,当烟雾浓度过高时,STM32 通过 PB7 引脚控制蜂鸣器发出警报声。

(四)射频模块
RC522 频射模块用于刷卡识别车辆,通过 PA3、PA2、PA1、PWM、VCC 和 GND 引脚与 STM32 连接。
当车辆进入停车场时,用户需要刷卡,RC522 频射模块读取卡片信息,并将信息通过 SPI(串行外设接口)或 IIC 等通信方式传输给 STM32 进行处理。

(五)Wi - Fi 模块
Wi - Fi 模块用于将停车场的数据上传至阿里云,通过 PA9 和 PA10 引脚与 STM32 连接。
STM32 通过串口与 Wi - Fi 模块进行通信,将停车场的信息(如空闲车位数量、停车时间、费用等)打包成特定的数据格式,发送给 Wi - Fi 模块,Wi - Fi 模块再将数据上传至阿里云服务器,用户可以通过手机 APP 或网页等方式访问阿里云服务器,获取停车场的实时信息。

四、软件设计

(一)操作系统选择
本系统采用了 UCOSIII 操作系统,它是一种实时操作系统,具有多任务管理、任务调度、中断管理等功能。UCOSIII 可以提高系统的实时性和可靠性,保证系统的稳定运行。

(二)任务划分
根据系统的功能需求,将系统划分为以下几个任务:

  1. 开始任务(start_task):创建完任务二和任务三就删除自己。
  2. 任务一(task1_task):亮灯,并打印出信息。
  3. 任务二(task2_task):打印任务二执行信息。
  4. 任务三(task3_task):收集超声波信息。

(三)任务实现

  1. 开始任务(start_task)
    • 任务优先级为 3,堆栈大小为 128。

    • 主要功能包括系统初始化、创建其他任务以及删除自身。

    • 具体步骤如下:

      • 进行系统初始化,包括时钟初始化、中断分组配置、串口初始化等。
      • 初始化各个外设模块,如舵机、LED、蜂鸣器、ADC、DHT11、OLED、RC522、定时器等。
      • 进入临界区,创建任务一、任务二和任务三。
      • 退出临界区,删除开始任务自身。

      在代码中,相关部分如下:

        // 开始任务函数
        void start_task(void *p_arg)
        {
            OS_ERR err;
            CPU_SR_ALLOC();
            p_arg = p_arg;

            CPU_Init();
            #if OS_CFG_STAT_TASK_EN > 0u
            OSStatTaskCPUUsageInit(&err);   // 统计任务
            #endif

            #ifdef CPU_CFG_INT_DIS_MEAS_EN  // 如果使能了测量中断关闭时间
            CPU_IntDisMeasMaxCurReset();
            #endif

            #if OS_CFG_SCHED_ROUND_ROBIN_EN  // 当使用时间片轮转的时候
            // 使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1 * 5 = 5ms
            OSSchedRoundRobinCfg(DEF_ENABLED, 1, &err);
            #endif

            OS_CRITICAL_ENTER();  // 进入临界区
            // 创建TASK1任务
            OSTaskCreate((OS_TCB *) &Task1_TaskTCB,
                (CPU_CHAR *) "Task1 task",
                (OS_TASK_PTR) task1_task,
                (void *) 0,
                (OS_PRIO) TASK1_TASK_PRIO,
                (CPU_STK *) &TASK1_TASK_STK[0],
                (CPU_STK_SIZE) TASK1_STK_SIZE / 10,
                (CPU_STK_SIZE) TASK1_STK_SIZE,
                (OS_MSG_QTY) 0,
                (OS_TICK) 0,
                (void *) 0,
                (OS_OPT) OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,
                (OS_ERR *) &err);

            // 创建TASK2任务
            OSTaskCreate((OS_TCB *) &Task2_TaskTCB,
                (CPU_CHAR *) "task2 task",
                (OS_TASK_PTR) task2_task,
                (void *) 0,
                (OS_PRIO) TASK2_TASK_PRIO,
                (CPU_STK *) &TASK2_TASK_STK[0],
                (CPU_STK_SIZE) TASK2_STK_SIZE / 10,
                (CPU_STK_SIZE) TASK2_STK_SIZE,
                (OS_MSG_QTY) 0,
                (OS_TICK) 0,
                (void *) 0,
                (OS_OPT) OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,
                (OS_ERR *) &err);

            // 创建TASK3任务
            OSTaskCreate((OS_TCB *) &Task3_TaskTCB,
                (CPU_CHAR *) "task3 task",
                (OS_TASK_PTR) task3_task,
                (void *) 0,
                (OS_PRIO) TASK3_TASK_PRIO,
                (CPU_STK *) &TASK3_TASK_STK[0],
                (CPU_STK_SIZE) TASK3_STK_SIZE / 10,
                (CPU_STK_SIZE) TASK3_STK_SIZE,
                (OS_MSG_QTY) 0,
                (OS_TICK) 0,
                (void *) 0,
                (OS_OPT) OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,
                (OS_ERR *) &err);

            OS_CRITICAL_EXIT();  // 退出临界区
            OSTaskDel((OS_TCB *) 0, &err);  // 删除start_task任务自身
        }
  1. 任务一(task1_task)
    • 任务优先级为 4,堆栈大小为 128。

    • 主要功能包括控制车门开关、检测环境数据、处理车位占用信息以及显示停车场数据。

    • 具体步骤如下:

      • 进入临界区和退出临界区,目前临界区未进行具体操作。
      • 根据车辆进出标志(car.in_out)控制车门开关。当车辆需要开关门时,根据报警标志(sys_flag.alarm)和车窗状态标志(sys_flag.window_flag)判断是否执行开门或关门操作,并更新相关标志和计时。
      • 读取 MQ2 传感器的数据获取烟雾浓度(sys_dat.air),并通过 DHT11 读取温湿度数据(sys_dat.temp 和 sys_dat.humi)。
      • 根据超声波检测结果更新车位占用标志(car._1_falg 和 car._2_falg)。
      • 当车辆进出标志为 0 时,调用 OLED_Display 函数显示停车场数据。
      • 根据烟雾浓度判断是否触发报警,控制蜂鸣器状态和危险信号标志位。
      • 延时 1 秒。

      在代码中,相关部分如下:

        // task1任务函数
        void task1_task(void *p_arg)
        {
            OS_ERR err;
            CPU_SR_ALLOC();
            p_arg = p_arg;

            OS_CRITICAL_ENTER();
            OS_CRITICAL_EXIT();
            while (1)
            {
                if (car.in_out == 1)  // 开关门
                {
                    if (sys_flag.alarm == 0 && sys_flag.window_flag == 0)  // 在关门状态下才能开门
                    {
                        SG90_angle(180);  // 开门
                        sys_flag.window_flag = 1;
                    }
                    if (++car.window_time >= 3)  // 开门间隔
                    {
                        if (sys_flag.alarm == 0 && sys_flag.window_flag == 1)  // 在开门状态下才能关门
                        {
                            OLED_Clear();  // 清屏
                            SG90_angle(0);  // 关门
                            sys_flag.window_flag = 0;
                            car.window_time = 0;
                        }
                        car.in_out = 0;
                    }
                }

                sys_dat.air = get_adc_value(ADC_Channel_8) / 40.96;  // PB0  MQ2
                DHT11_Read_Data(&sys_dat.temp, &sys_dat.humi);  // PA4  温湿度检测

                if (car.in_out == 0)
                {
                    OLED_Display();
                }

                if (car.SR04_1 < 5)
                {
                    car._1_falg = 1;
                }
                else
                {
                    car._1_falg = 0;
                }
                if (car.SR04_2 < 5)
                {
                    car._2_falg = 1;
                }
                else
                {
                    car._2_falg = 0;
                }

                if (sys_dat.air > air_threshold)  // 烟雾过高报警
                {
                    BEEP_ON;  // 危险报警
                    sys_flag.beep_flag = 1;  // 蜂鸣器状态
                    sys_flag.alarm = 1;  // 危险信号标志位
                }
                else
                {
                    BEEP_OFF;  // 消除危险报警
                    sys_flag.beep_flag = 0;  // 蜂鸣器状态
                    sys_flag.alarm = 0;  // 危险信号标志位
                }

                OSTimeDlyHMSM(0, 0, 2, 0, OS_OPT_TIME_HMSM_STRICT, &err);  // 延时1s
            }
        }
  1. 任务二(task2_task)
    • 任务优先级为 5,堆栈大小为 512。

    • 主要功能是处理刷卡信息,包括读取卡片 ID、记录车辆信息、计算费用和余额、更新车辆状态等。

    • 具体步骤如下:

      • 进入临界区和退出临界区,目前临界区未进行具体操作。
      • 通过 RC522 射频模块进行刷卡操作,获取卡片信息。
      • 判断刷卡是否成功,如果成功,则读取卡片 ID 并进行相关处理。
      • 遍历记录的卡片信息数组,判断当前卡片是否已存在。如果已存在,根据车辆驶出或进入的标志进行相应的处理,包括计算费用、更新余额、上传数据等。如果是新卡,则将其信息记录到数组中,并设置相应的车辆状态和余额。
      • 控制 OLED 显示相关信息,如卡号、车辆驶入或驶出状态、时间、费用、余额等。
      • 遍历车辆信息数组,根据车辆状态更新时间信息。
      • 发布 MQTT 消息,上传停车场数据。
      • 延时 1 秒。
       

      在代码中,相关部分如下:

        // task2任务函数
        void task2_task(void *p_arg)
        {
            OS_ERR err;
            CPU_SR_ALLOC();
            p_arg = p_arg;
            int i;

            u8 temp_buff[20] = {0}, temp = 0;

            OS_CRITICAL_ENTER();  // 进入临界区
            OS_CRITICAL_EXIT();  // 退出临界区域
            while (1)
            {
                status = PcdRequest(REQ_ALL, TagType);
                if (!status)
                {
                    status = PcdAnticoll(SelectedSnr);
                    if (!status)
                    {
                        status = PcdSelect(SelectedSnr);
                        if (!status)
                        {
                            snr = 1;  // 扇区号1
                            status = PcdAuthState(KEYA, (snr * 4 + 3), DefaultKey, SelectedSnr);  // 校验1扇区密码,密码位于每一扇区第3块
                            {
                                if (!status)
                                {
                                    status = PcdRead((snr * 4 + 0), buf);  // 读卡,读取1扇区0块数据到buf[0] - buf[16]
                                    if (!status)
                                    {
                                        OLED_Clear();  // 清屏
                                        sprintf((char *)ID_Card, ":%d%d%d%d", SelectedSnr[0], SelectedSnr[1], SelectedSnr[2], SelectedSnr[3]);
                                        OLED_ASCII_GB2312_Show(0, 2, "卡号");  // 显示

4. 任务三(task3_task) - 任务优先级为 6,堆栈大小为 128。 - 主要功能是收集超声波信息,获取车位与障碍物之间的距离。 - 具体步骤如下: - 进入临界区和退出临界区,目前临界区未进行具体操作。 - 通过 SR04_1_DataMean 和 SR04_2_DataMean 函数获取两个超声波模块检测到的距离数据,并将其存储在 car.SR04_1 和 car.SR04_2 中。 - 延时 1 秒。 在代码中,相关部分如下: ```c // task3任务函数 void task3_task(void *p_arg) { OS_ERR err; CPU_SR_ALLOC(); p_arg = p_arg; OS_CRITICAL_ENTER(); // 进入临界区 OS_CRITICAL_EXIT(); // 退出临界区域 while (1) { car.SR04_1 = SR04_1_DataMean(); // 超声波的数据采集(平均值) car.SR04_2 = SR04_2_DataMean(); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // 延时1s } }

(四)显示函数

  • OLED_Display函数用于显示停车场的数据,包括车位状态、车位灯状态、车门状态、烟雾浓度、温度和湿度等信息。

  • 在函数中,通过OLED_ASCII_GB2312_ShowOLED_ASCII_ShowString函数在 OLED 显示屏上显示相应的文字和数据。

    在代码中,相关部分如下:

        // 显示停车场数据
        void OLED_Display(void)
        {
            // OLED_ASCII_GB2312_Show(0, 0, "停车场系统");  // 显示英文,汉字字符串
            OLED_ASCII_GB2312_Show(0, 0, "位");  // 显示英文,汉字字符串
            sprintf(temp_buff[0], "1:%d", car._1_falg);
            OLED_ASCII_ShowString(16, 0, temp_buff[0]);
            OLED_ASCII_GB2312_Show(60, 0, "位");  // 显示英文,汉字字符串
            sprintf(temp_buff[1], "2:%d", car._2_falg);
            OLED_ASCII_ShowString(76, 0, temp_buff[1]);
            OLED_ASCII_GB2312_Show(0, 2, "灯");  // 显示英文,汉字字符串
            sprintf(temp_buff[2], "1:%d", sys_flag.led1_flag);
            OLED_ASCII_ShowString(16, 2, temp_buff[2]);
            OLED_ASCII_GB2312_Show(60, 2, "灯");  // 显示英文,汉字字符串
            sprintf(temp_buff[3], "2:%d", sys_flag.led2_flag);
            OLED_ASCII_ShowString(76, 2, temp_buff[3]);
            OLED_ASCII_GB2312_Show(0, 4, "门");  // 显示英文,汉字字符串
            sprintf(temp_buff[4], ":%d", sys_flag.window_flag);
            OLED_ASCII_ShowString(16, 4, temp_buff[4]);
            OLED_ASCII_GB2312_Show(60, 4, "烟");  // 显示英文,汉字字符串
            sprintf(temp_buff[5], ":%d", (int)sys_dat.air);
            OLED_ASCII_ShowString(76, 4, temp_buff[5]);
            OLED_ASCII_GB2312_Show(0, 6, "温");  // 显示英文,汉字字符串
            sprintf(temp_buff[6], ":%d", (int)sys_dat.temp);
            OLED_ASCII_ShowString(16, 6, temp_buff[6]);
            OLED_ASCII_GB2312_Show(60, 6, "湿");  // 显示英文,汉字字符串
            sprintf(temp_buff[7], ":%d", (int)sys_dat.humi);
            OLED_ASCII_ShowString(76, 6, temp_buff[7]);
        }

五、软件设计中的关键技术

(一)临界区保护
在 UCOS III 中,使用 OS_CRITICAL_ENTER 和 OS_CRITICAL_EXIT 宏来保护临界区。当一个任务或中断进入临界区时,它必须调用 OS_CRITICAL_ENTER 宏以获得临界区的保护,禁用中断,确保执行临界区的代码不会被中断或抢占,从而保证了临界区的原子性。当代码执行完毕时,任务或中断必须调用 OS_CRITICAL_EXIT 宏来恢复中断。

(二)任务优先级调度
UCOS III 使用抢占式调度,任务的执行顺序基于优先级。具有更高优先级的任务比低优先级的任务更可能得到调度。当有一个高优先级的任务就绪时,当前正在执行的任务将被中断并且高优先级任务将被执行。任务切换通常发生在任务主动调用相关函数退让 CPU 或中断服务程序执行时。

(三)传感器数据处理
对于 DHT11 传感器,通过特定的通信协议获取温湿度数据,并进行相应的处理和转换。对于 MQ - 2 传感器,将模拟信号通过 ADC 转换为数字信号,以获取烟雾浓度数据。对于 HC - SR04 超声波模块,通过精确计时超声波的发射和接收时间差,根据声速计算出距离。

(四)射频模块通信
RC522 频射模块通过特定的通信接口(如 SPI 或 IIC)与 STM32 进行通信,STM32 发送指令控制 RC522 进行刷卡操作,RC522 将读取到的卡片信息返回给 STM32 进行处理。

(五)数据显示与上传
OLED 显示模块通过特定的显示指令和数据格式进行控制,以显示停车场的各种信息。Wi - Fi 模块通过串口与 STM32 进行通信,STM32 将停车场的数据打包成特定的格式发送给 Wi - Fi 模块,Wi - Fi 模块再将数据上传至阿里云服务器。

六、系统测试与结果分析

(一)测试环境搭建
搭建实际的停车场测试环境,安装好各个硬件模块,连接好电路,确保系统正常运行。设置相关的测试设备,如模拟车辆进出的卡片、障碍物等。

(二)功能测试

  1. 车辆进出测试
    • 测试刷卡功能,验证车辆能否正常进出停车场,计时计费是否准确。
    • 检查车门开关控制是否正常,车窗状态标志是否正确更新。
  2. 车位检测测试
    • 放置障碍物在车位上,测试超声波模块能否准确检测车位是否被占用。
    • 验证 OLED 显示屏上的车位状态信息是否与实际情况相符。
  3. 环境监测测试
    • 模拟不同的温湿度和烟雾浓度环境,测试 DHT11 和 MQ - 2 模块的检测准确性。
    • 检查报警功能是否在烟雾浓度过高时正常触发。
  4. 数据上传测试
    • 查看阿里云平台上是否能正常接收停车场的数据,包括空闲车位、停车时间、费用等信息。
    • 验证手机 APP 能否实时显示停车场的相关信息。

(三)结果分析
通过对系统进行全面测试,各项功能均能正常实现。车辆进出计时计费准确,车位检测灵敏可靠,环境监测数据准确,报警功能正常,数据上传稳定。OLED 显示屏能够清晰显示停车场的各种信息,用户可以通过手机方便地了解停车场的情况。

七、结论

本文设计的基于 STM32 的智能停车场管理系统,通过合理的硬件设计和软件编程,实现了预期的功能。该系统具有较高的稳定性和可靠性,能够提高停车场的管理效率和用户体验。在实际应用中,还可以根据具体需求进行进一步的优化和扩展,如增加车位引导功能、实现远程控制等。未来,随着物联网技术的不断发展,智能停车场管理系统将具有更广阔的应用前景。

程序源码&原理图&设计原理&设计文档&演示视频&框图等

资料下载链接:

基于STM32+手机APP设计的智能停车场系统-程序源码&原理图&设计文档&演示视频&框图等(毕设/课设/竞赛/实训/项目等)资源-CSDN文库icon-default.png?t=N7T8https://download.csdn.net/download/m0_61712829/89651449

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿齐Archie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值