实时时钟项目设计

 项目流程图

即核心代码为修改时间部分 :①当按下key1时,进入到修改时间的部分,此时再按下key2会偏移修改的位置,按下key3和key4时会增加数值和减少数值(有范围限制)按下key1会保存和退出当前模式,②当按下key2时会进入到闹钟的修改部分,同时key2偏移 key1 保存和退出,key3 4 增加数值或者减少数值③按下key 3 key4 停止蜂鸣器报警

rtc内置时钟运行规则,可以直接通过RTC寄存器获取时间,无需手动计算进位。

main.c函数如下

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"
#include "beep.h"
#include "key.h"
#include "oled.h"
#include "rtc.h"



int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
//  led_init();
    uart1_init(115200);
    beep_init();
    KEY_init();
    oled_init();
    rtc_init();
    printf("hello world!\r\n");
    
    
    uint8_t time_data[6] = {25 , 5, 17, 19, 40, 30};
    uint8_t alarm_data[3] = {17, 50, 40};
    uint8_t set_time_shift = TIME_SECOND;     //默认的情况下先改秒的坑位
    uint8_t set_alarm_shift = ALARM_SECOND;
    uint8_t set_time_flag =0,set_alarm_flag =0 ;

    oled_show_init();
    
    if(rtc_read_bkr(1) !=0xA5A5)
    {
        rtc_write_bkr(1,0xA5A5);
        
        rtc_set_time(time_data);
        rtc_set_alarm(alarm_data);

    }
    
    while(1)
    { 
      
        //获取时间及闹钟
        rtc_get_time(time_data);
        rtc_get_alarm(alarm_data);
        
        //并在oled屏上进行显示
        oled_show_time_alarm(time_data,alarm_data);
        //delay_ms(1000);
        switch(KEY_scan())
        {
            case KEY_SET:
                //进入到时间设置模式
            set_time_flag=1;
            while(set_time_flag)
            {
                //闪动要修改的坑位
                oled_show_element(time_data[set_time_shift],OFF,set_time_shift);
                delay_ms(100);
                oled_show_element(time_data[set_time_shift],ON,set_time_shift);
                delay_ms(100);
                switch (KEY_scan())
                {
                    case KEY_SET:
                        //退出时间设置模式
                    
                    set_time_flag=0;
                    set_time_shift =TIME_SECOND;
                    //保存修改后的时间
                    rtc_set_time(time_data);
                        break;
                    case KEY_SHIFT:
                        //跳转到下一个需要修改的元素(秒 分 时 日 月 年)
                    if(set_time_shift-- <= TIME_YEAR)
                    {
                        set_time_shift =TIME_SECOND;
                    }
                        break;
                    
                    case KEY_UP:

                    //增加数值
                        
                    if(set_time_shift ==TIME_SECOND || set_time_shift ==TIME_MINUTE )    // 分 秒
                        if(time_data[set_time_shift] <59)
                            time_data[set_time_shift]++;
                    if(set_time_shift ==TIME_HOUR )    // 时
                        if(time_data[set_time_shift] <23)
                            time_data[set_time_shift]++;
                    if(set_time_shift ==TIME_DAY )    // 日
                        if(time_data[set_time_shift] <31)
                            time_data[set_time_shift]++;
                    if(set_time_shift ==TIME_MONTH )    // 月
                        if(time_data[set_time_shift] <23)
                            time_data[set_time_shift]++;
                    if(set_time_shift ==TIME_YEAR )    // 年
                        if(time_data[set_time_shift] <99)
                            time_data[set_time_shift]++;
                        
                    break;
                     
                    case KEY_DOWN:
                        
                    //减少数值
                    if(time_data[set_time_shift] >0)
                        time_data[set_time_shift]--;
                    break;
                    
                    default:
                        break;                    
                    
              
                }
            }
                break;
            case KEY_SHIFT:
                //进入闹钟设置模式
            set_alarm_flag =1;
            while(set_alarm_flag)
            {
                 //闪动要修改的坑位
                oled_show_element(alarm_data[set_alarm_shift - ALARM_HOUR],OFF,set_alarm_shift);
                delay_ms(100);
                oled_show_element(alarm_data[set_alarm_shift - ALARM_HOUR],ON,set_alarm_shift);
                delay_ms(100);
                 switch(KEY_scan())
                 {
                 
                   case KEY_SET:
                       //退出闹钟设置模式
                   set_alarm_flag=0;
                   set_alarm_shift =ALARM_SECOND;
                       //保存修改后的闹钟
                   rtc_set_alarm(alarm_data);
                       break;
                   
                   case KEY_SHIFT:
                       //跳转到下一个需要修改的元素(秒 分 时)
                   if(set_alarm_shift-- <= ALARM_HOUR)
                    {
                        set_alarm_shift =ALARM_SECOND;
                    }
                   
                       break;
                   
                   case KEY_UP:
                       //增加数值
                   if(alarm_data[set_alarm_shift -ALARM_HOUR] <59)
                       alarm_data[set_alarm_shift-ALARM_HOUR] ++;
                       break;
                   
                   
                   case KEY_DOWN:
                       //减少数值
                       if(alarm_data[set_alarm_shift -ALARM_HOUR] >0)
                       alarm_data[set_alarm_shift-ALARM_HOUR] --;
                       break;
                   
                 
                 default:
                     break;
                 
                 
                 }
            
            
            
            
            }
                break;
            case KEY_UP:
            case KEY_DOWN:
                //停止蜂鸣器
                beep_off();
                break;
            
        
        
        
        
        
        }
    }
}

  

oled.c代码如下

#include "oled.h"
#include "font.h"
#include "delay.h"

void oled_gpio_init(void)
{
    GPIO_InitTypeDef gpio_initstruct;
    OLED_I2C_SCL_CLK();
    OLED_I2C_SDA_CLK();
    gpio_initstruct.Pin = OLED_I2C_SCL_PIN;                         //LED1、LED2对应的引脚
    gpio_initstruct.Pull = GPIO_PULLUP;                       //上拉
    gpio_initstruct.Mode =GPIO_MODE_OUTPUT_PP;                //开漏输出
    gpio_initstruct.Speed =GPIO_SPEED_FREQ_HIGH;              //高速
    HAL_GPIO_Init(OLED_I2C_SCL_PORT,&gpio_initstruct);
    
    
    
    gpio_initstruct.Pin = OLED_I2C_SDA_PIN;                         //LED1、LED2对应的引脚
    HAL_GPIO_Init(OLED_I2C_SDA_PORT,&gpio_initstruct);
}

void oled_i2c_start(void)
{
    OLED_SCL_SET();
    OLED_SDA_SET();
    OLED_SDA_RESET();
    OLED_SCL_RESET();
}

void oled_i2c_stop(void)
{
    OLED_SCL_SET();
    OLED_SDA_RESET();
    OLED_SDA_SET();
    
}
void oled_i2c_ack(void)
{
    OLED_SCL_SET();
    OLED_SCL_RESET();

}
void oled_i2c_write_byte(uint8_t data)                     //发送一个字节8位并保存数据 保存数据是偏移后的第一位如果是1则置SDA为高电平 反之则置低电平
{

    uint8_t i,tmp;
    tmp= data;
    for(i=0;i<8;i++)
    {

    if((tmp & 0x80) == 0x80)                   //“与” AND的运算1&0=0 0&0=0 1&1=1  这是为了看最高位是否为1
        OLED_SDA_SET();
    else
     
        OLED_SDA_RESET();
       
    tmp=tmp << 1;
    OLED_SCL_SET();
    OLED_SCL_RESET();
    
}
}
void oled_write_cmd(uint8_t cmd)
{
    oled_i2c_start();
    oled_i2c_write_byte(0x78);
    oled_i2c_ack();
    oled_i2c_write_byte(0x00);
    oled_i2c_ack();
    oled_i2c_write_byte(cmd);
    oled_i2c_ack();
    oled_i2c_stop();
    

}
void oled_write_data(uint8_t data)
    
{
    oled_i2c_start();
    oled_i2c_write_byte(0x78);
    oled_i2c_ack();
    oled_i2c_write_byte(0x40);
    oled_i2c_ack();
    oled_i2c_write_byte(data);
    oled_i2c_ack();
    oled_i2c_stop();
    

}


void oled_init(void)
{
    
    oled_gpio_init();
    
    delay_ms(100);
    oled_write_cmd(0xAE);    //设置显示开启/关闭,0xAE关闭,0xAF开启

    oled_write_cmd(0xD5);    //设置显示时钟分频比/振荡器频率
    oled_write_cmd(0x80);    //0x00~0xFF

    oled_write_cmd(0xA8);    //设置多路复用率
    oled_write_cmd(0x3F);    //0x0E~0x3F

    oled_write_cmd(0xD3);    //设置显示偏移
    oled_write_cmd(0x00);    //0x00~0x7F

    oled_write_cmd(0x40);    //设置显示开始行,0x40~0x7F

    oled_write_cmd(0xA1);    //设置左右方向,0xA1正常,0xA0左右反置

    oled_write_cmd(0xC8);    //设置上下方向,0xC8正常,0xC0上下反置

    oled_write_cmd(0xDA);    //设置COM引脚硬件配置
    oled_write_cmd(0x12);

    oled_write_cmd(0x81);    //设置对比度
    oled_write_cmd(0xCF);    //0x00~0xFF

    oled_write_cmd(0xD9);    //设置预充电周期
    oled_write_cmd(0xF1);

    oled_write_cmd(0xDB);    //设置VCOMH取消选择级别
    oled_write_cmd(0x30);

    oled_write_cmd(0xA4);    //设置整个显示打开/关闭

    oled_write_cmd(0xA6);    //设置正常/反色显示,0xA6正常,0xA7反色

    oled_write_cmd(0x8D);    //设置充电泵
    oled_write_cmd(0x14);

    oled_write_cmd(0xAF);    //开启显示
    
    oled_fill(0x00);         //及时清空避免出现雪花现象

}
void oled_set_cursor(uint8_t x, uint8_t y)              //设置写的位置在哪里  y为page x为列
{
    oled_write_cmd(0xB0 + y);    //设置page
    /*设置哪一列*/
    oled_write_cmd(( x & 0x0F) | 0x00);
    oled_write_cmd((x & 0xF0) >> 4 | 0x10 );

}
void oled_fill(uint8_t data)            //注意oled_set_cursor(0, i);  的位置是因为这里的寻址模式采用的是页地址的寻址模式
{
    uint8_t i, j;
    for(i = 0; i < 8; i++)
    {
        oled_set_cursor(0, i);
        for(j = 0; j < 128; j++)
        {
            
            oled_write_data(data);
        }
    }
}
void oled_show_char(uint8_t x,uint8_t y ,uint8_t num,uint8_t size)     //y为哪一行  x为哪一列,num为ascii值,size为高度  设置了三个高度 12 16 24 
{
    uint8_t i,j,page;
    num=num-' ';
    
    page =size / 8;
    if(size % 8 != 0)
        page++;
    
    for(j= 0;j<page;j++)
    {
        oled_set_cursor(x,y + j);
        for( i = size / 2 * j;  i < size / 2 * ( j + 1 ) ; i++)
        {
        if(size == 12)
            oled_write_data(ascii_6X12[num][i]);
        else if(size == 16)
            oled_write_data(ascii_8X16[num][i]);
        else if(size == 24)
            oled_write_data(ascii_12X24[num][i]);
        
        
        }
    
    }
  

}

void oled_show_string(uint8_t x,uint8_t y,char *p, uint8_t size)            //第三个参数为字符串的内容
{

    while(*p != '\0')
    {
        oled_show_char(x, y,*p,size);
        x +=size/2;
        p++;
    
    
    }

}

//void oled_show_chinese(uint8_t x, uint8_t y, uint8_t N, uint8_t size)       //N为汉字的位数
//{
//    uint16_t i, j;
//    for(j = 0; j < size/8; j++)
//    {
//        oled_set_cursor(x, y + j);
//        for(i = size *j; i < size * (j + 1); i++)
//        {
//            if(size == 16)
//                oled_write_data(chinese_16x16[N][i]);
//            else if(size == 24)
//                oled_write_data(chinese_24x24[N][i]);
//        }
//    }
//}

void oled_show_chinese(uint8_t x, uint8_t y, uint8_t N)       //N为汉字的位数
{
    uint16_t i, j;
    for(j = 0; j < 2; j++)
    {
        oled_set_cursor(x, y + j);
        for(i = 16 *j; i < 16 * (j + 1); i++)
        {
         oled_write_data(chinese_time[N][i]);
         
        }
        }
    }


void oled_show_init(void)
{
    oled_fill(0x00);
    oled_show_string(8,0,"2000",16);                //2025
    oled_show_chinese(40,0,0);                       //年
    oled_show_string(56,0,"00",16);                    //05
    oled_show_chinese(72,0,1);                         //月
    oled_show_string(88,0,"00",16);                   //17
    oled_show_chinese(104,0,2);                        //日
    
    oled_show_string(26,2,"00",16);                //17
    oled_show_char(45,2,':',16);                    //:
    oled_show_string(56,2,"00",16);                //30
    oled_show_char(75,2,':',16);                   //:
    oled_show_string(86,2,"00",16);                //30

    
    oled_show_chinese(10,4,3);                       //闹
    oled_show_chinese(26,4,4);                         //钟
    oled_show_char(42,4,':',16);                   //:
    
    oled_show_string(26,6,"00",16);                //17
    oled_show_char(45,6,':',16);                       //:
    oled_show_string(56,6,"00",16);                    //31
    oled_show_char(75,6, ':',16);                         //:
    oled_show_string(86,6, "00",16);                   //30

    
    
    
}

void oled_clear_2char(uint8_t x, uint8_t y)
{
    uint8_t i=0;
    oled_set_cursor(x,y);
    for(i=0;i<16;i++)
    oled_write_data(0x00);
    
    
    oled_set_cursor(x,y+1);
    for(i=0;i<16;i++)
    oled_write_data(0x00);


}
//年
void oled_show_year(uint8_t num,uint8_t display_flag)         //display_flag的效果是当置1时存在 置0时不存在
{
    if(display_flag)
    {
    
        //显示年份的坑位
        oled_show_char(24,0, num/10+ '0',16);
        oled_show_char(32,0, num%10+ '0',16);
    
    }
    else
        //不显示年份的坑位
    oled_clear_2char(24,0);

}

//月
void oled_show_month(uint8_t num, uint8_t display_flag)
{
    if(display_flag)
    {
        oled_show_char(56, 0, num/10 + '0', 16);
        oled_show_char(64, 0, num%10 + '0', 16);
    }
    else
        oled_clear_2char(56, 0);
}

//日
void oled_show_day(uint8_t num, uint8_t display_flag)
{
    if(display_flag)
    {
        oled_show_char(88, 0, num/10 + '0', 16);
        oled_show_char(96, 0, num%10 + '0', 16);
    }
    else
        oled_clear_2char(88, 0);
}

//时
void oled_show_hour(uint8_t num, uint8_t display_flag)
{
    if(display_flag)
    {
        oled_show_char(26, 2, num/10 + '0', 16);
        oled_show_char(34, 2, num%10 + '0', 16);
    }
    else
        oled_clear_2char(26, 2);
}

//分
void oled_show_minute(uint8_t num, uint8_t display_flag)
{
    if(display_flag)
    {
        oled_show_char(56, 2, num/10 + '0', 16);
        oled_show_char(64, 2, num%10 + '0', 16);
    }
    else
        oled_clear_2char(56, 2);
}

//秒
void oled_show_second(uint8_t num, uint8_t display_flag)
{
    if(display_flag)
    {
        oled_show_char(86, 2, num/10 + '0', 16);
        oled_show_char(94, 2, num%10 + '0', 16);
    }
    else
        oled_clear_2char(86, 2);
}

//闹钟:时
void oled_show_alarm_hour(uint8_t num, uint8_t display_flag)
{
    if(display_flag)
    {
        oled_show_char(26, 6, num/10 + '0', 16);
        oled_show_char(34, 6, num%10 + '0', 16);
    }
    else
        oled_clear_2char(26, 6);
}

//闹钟:分
void oled_show_alarm_minute(uint8_t num, uint8_t display_flag)
{
    if(display_flag)
    {
        oled_show_char(56, 6, num/10 + '0', 16);
        oled_show_char(64, 6, num%10 + '0', 16);
    }
    else
        oled_clear_2char(56, 6);
}

//闹钟:秒
void oled_show_alarm_second(uint8_t num, uint8_t display_flag)
{
    if(display_flag)
    {
        oled_show_char(86, 6, num/10 + '0', 16);
        oled_show_char(94, 6, num%10 + '0', 16);
    }
    else
        oled_clear_2char(86, 6);
}

void oled_show_element(uint8_t num, uint8_t display_flag,uint8_t element)     //让哪一个元素显示

{
    switch(element)
    {
        case  TIME_YEAR:
            oled_show_year(num,display_flag); 
        break;
        case  TIME_MONTH:
            oled_show_month(num,display_flag); 
        break;
        case  TIME_DAY:
            oled_show_day(num,display_flag); 
        break;
        case  TIME_HOUR:
            oled_show_hour(num,display_flag); 
        break;
        case  TIME_MINUTE:
            oled_show_minute(num,display_flag); 
        break;
        case  TIME_SECOND:
            oled_show_second(num,display_flag); 
        break;
        case  ALARM_HOUR:
            oled_show_alarm_hour(num,display_flag); 
        break;
        case  ALARM_MINUTE:
            oled_show_alarm_minute(num,display_flag); 
        break;
        case  ALARM_SECOND:
            oled_show_alarm_second(num,display_flag); 
        break;
        default : break ;
    
    
    
    
    
    }



}

void oled_show_time_alarm(uint8_t *time,uint8_t *alarm)
{
        
    oled_show_year(time[0],ON);
    oled_show_month(time[1],ON);
    oled_show_day(time[2],ON);
    oled_show_hour(time[3],ON);
    oled_show_minute(time[4],ON);
    oled_show_second(time[5],ON);
    oled_show_alarm_hour(alarm[0],ON);
    oled_show_alarm_minute(alarm[1],ON);
    oled_show_alarm_second(alarm[2],ON);


}
    


void oled_show_image(uint8_t x,uint8_t y,uint8_t width,uint8_t height,uint8_t *bmp)            //其中参数bmp为指针
{
    uint8_t i,j;
    for(j=0;j<height;j++)
    {
        oled_set_cursor(x,y+j);
        for(i=0;i<width;i++)
        oled_write_data(bmp[width * j +i]);
    
    }



}

rtc.c代码如下

#include "rtc.h"
#include "stdio.h"
#include "beep.h"



RTC_HandleTypeDef rtc_handle ={0};
void rtc_init(void)
{
    __HAL_RCC_PWR_CLK_ENABLE();
    __HAL_RCC_BKP_CLK_ENABLE();
    HAL_PWR_EnableBkUpAccess();
    
    rtc_handle.Instance =RTC;             //基地址
    rtc_handle.Init.AsynchPrediv =32767;                //分频系数
    rtc_handle.Init.OutPut = RTC_OUTPUTSOURCE_NONE;            //不使用侵入检测
    HAL_RTC_Init(&rtc_handle);

}
void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
{
    __HAL_RCC_RTC_ENABLE();
    RCC_OscInitTypeDef osc_initstruct = {0};
    RCC_PeriphCLKInitTypeDef periphclk_initstruct ={0};
    
    //配置LSE
    osc_initstruct.OscillatorType =RCC_OSCILLATORTYPE_LSE;         //设置的振荡器的类型  低速外部振荡器
    osc_initstruct.LSEState = RCC_LSE_ON;                     //设置LSE为开启状态  
    osc_initstruct.PLL.PLLState =RCC_PLL_NONE;                  //关闭锁相环   即不能将低频时钟信号转换为高频时钟信号
    HAL_RCC_OscConfig(&osc_initstruct);
    
    
    //配置RTC时钟源
    periphclk_initstruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;               //配置外设时钟类型为RTC
    periphclk_initstruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;                //使用外部低速晶振
    HAL_RCCEx_PeriphCLKConfig(&periphclk_initstruct);
    
    HAL_NVIC_SetPriority(RTC_Alarm_IRQn,2,2);
    HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);

}
void RTC_Alarm_IRQHandle(void)     //中断服务函数
{

    HAL_RTC_AlarmIRQHandler(&rtc_handle);           //公共服务函数

}

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
        printf("ring ring ring ... \r\n");
        beep_on();
}
uint16_t rtc_read_bkr(uint8_t bkrx)     //其中参数bkrx为指定哪个寄存器
{
    uint32_t data =0;
    data = HAL_RTCEx_BKUPRead(&rtc_handle,bkrx);
    return (uint16_t)data;

}

void rtc_write_bkr(uint8_t bkrx,uint16_t data)     //其中参数bkrx为指定哪个寄存器  data为写什么东西
{
    HAL_RTCEx_BKUPWrite(&rtc_handle,bkrx,data);

}

void rtc_get_time(uint8_t *time_data)                                         //获取时间
{
    RTC_TimeTypeDef rtc_time ={0};
    RTC_DateTypeDef rtc_date ={0};
    
    
    
    HAL_RTC_GetTime(&rtc_handle,&rtc_time,RTC_FORMAT_BIN);   //第二个参数将得到的时间储存在这里,第三个参数是形式是什么
    HAL_RTC_GetDate(&rtc_handle,&rtc_date,RTC_FORMAT_BIN);  //日期
    
    time_data[0] = rtc_date.Year;
    time_data[1] = rtc_date.Month;
    time_data[2] = rtc_date.Date;
    time_data[3] = rtc_time.Hours;
    time_data[4] = rtc_time.Minutes;
    time_data[5] = rtc_time.Seconds;
   // printf("rtc time: %d-%02d-%02d %02d:%02d:%02d\r\n", rtc_date.Year+2000,rtc_date.Month,rtc_date.Date,rtc_time.Hours,rtc_time.Minutes,rtc_time.Seconds );
    
}


void rtc_set_time(uint8_t *time_data)                         //设置时间
{
    RTC_TimeTypeDef rtc_time ={0};
    RTC_DateTypeDef rtc_date ={0};
    
    rtc_time.Hours = time_data[3];
    rtc_time.Minutes = time_data[4];
    rtc_time.Seconds = time_data[5];
    HAL_RTC_SetTime(&rtc_handle,&rtc_time,RTC_FORMAT_BIN);
    
    
    rtc_date.Year = time_data[0];
    rtc_date.Month =time_data[1];
    rtc_date.Date = time_data[2];
    
    HAL_RTC_SetDate(&rtc_handle,&rtc_date,RTC_FORMAT_BIN);
    
    while(!__HAL_RTC_ALARM_GET_FLAG(&rtc_handle,RTC_FLAG_RTOFF));   //对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行,可以通过查询RTC_CR寄存器中的RTOFF转台为,判断RTC寄存器是否处于更新中,仅当RTOFF状态位是1时,才可以写入RTC寄存器

}


void rtc_get_alarm(uint8_t *alarm_data)
{
    RTC_AlarmTypeDef alarm ={0};
    HAL_RTC_GetAlarm(&rtc_handle,&alarm,RTC_ALARM_A,RTC_FORMAT_BIN);
    alarm_data[0]= alarm.AlarmTime.Hours;
    alarm_data[1]= alarm.AlarmTime.Minutes;
    alarm_data[2]= alarm.AlarmTime.Seconds;
}
    


void rtc_set_alarm(uint8_t *alarm_data)           //设置闹钟
{
    
    RTC_AlarmTypeDef alarm = {0};
    alarm.Alarm =RTC_ALARM_A;      //闹钟的类型
    alarm.AlarmTime.Hours = alarm_data[0];
    alarm.AlarmTime.Minutes = alarm_data[1];
    alarm.AlarmTime.Seconds = alarm_data[2];
    
    HAL_RTC_SetAlarm_IT(&rtc_handle,&alarm,RTC_FORMAT_BIN);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值