AutoLeaders控制组——51单片机学习任务(二)

一、补充

1.1 模块化编程

原代码:

#include <REGX52.H>

unsigned char NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //ÊýÂë¹Ü¶ÎÂë±í

void Delay(unsigned int xms)	//
{
		unsigned char i, j;
    while(xms--)
		{
				i = 2;
				j = 199;
				do
				{
						while (--j);
				} while (--i);
		}
}

void Nixie(unsigned char Location, Number)
{
		switch(Location)
		{
				case 1:P2_4=1;P2_3=1;P2_2=1;break;
			  	case 2:P2_4=1;P2_3=1;P2_2=0;break;
				case 3:P2_4=1;P2_3=0;P2_2=1;break;
				case 4:P2_4=1;P2_3=0;P2_2=0;break;
				case 5:P2_4=0;P2_3=1;P2_2=1;break;
				case 6:P2_4=0;P2_3=1;P2_2=0;break;
				case 7:P2_4=0;P2_3=0;P2_2=1;break;
				case 8:P2_4=0;P2_3=0;P2_2=0;break;
		}
		P0=NixieTable[Number];
		Delay(1);
		P0=0x00;        //消影,清零
}

void main()
{
		while(1)
		{
				Nixie(2,3);   //第二个数码管显示3
				Delay(1);
				Nixie(3,7);
				Delay(1);
				Nixie(6,6);
				Delay(1);
		}
}

烧录结果:
请添加图片描述
代码多少有些冗长,我们可以对一些功能代码进行模块化
比如延时(Delay):
建立Delay.c:

void Delay(unsigned int xms)	//
{
		unsigned char i, j;
    while(xms--)
		{
				i = 2;
				j = 199;
				do
				{
						while (--j);
				} while (--i);
		}
}

建立Delay.h:(建头文件拿来用)

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);
	
#endif

于是,只需要一个“ #include “Delay.h” ”就能随意使用Delay()

数码管(Nixie)同理:
建立Nixie.c:

#include <REGX52.H>
#include "Delay.h"

unsigned char NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; 

void Nixie(unsigned char Location, Number)
{
		switch(Location)
		{
				case 1:P2_4=1;P2_3=1;P2_2=1;break;
			  	case 2:P2_4=1;P2_3=1;P2_2=0;break;
				case 3:P2_4=1;P2_3=0;P2_2=1;break;
				case 4:P2_4=1;P2_3=0;P2_2=0;break;
				case 5:P2_4=0;P2_3=1;P2_2=1;break;
				case 6:P2_4=0;P2_3=1;P2_2=0;break;
				case 7:P2_4=0;P2_3=0;P2_2=1;break;
				case 8:P2_4=0;P2_3=0;P2_2=0;break;
		}
		P0=NixieTable[Number];
		Delay(1);
		P0=0x00;        
}

建立Nixie.h:

#ifndef __NIXIE_H__
#define __NIXIE_H__

void Nixie(unsigned char Location, Number);

#endif

于是,主文件就变成了这样,只需引用Delay与Nixie模块,就可以极简达成原来的效果:

#include <REGX52.H>
#include "Delay.h"
#include "Nixie.h"

void main()
{
		while(1)
		{
				Nixie(2,3);  
				Delay(1);
				Nixie(3,7);
				Delay(1);
				Nixie(6,6);
				Delay(1);
		}
}

1.2 LCD1602调试工具

讲LCD1602插入槽口:
请添加图片描述

头文件:LCD1602.h(调用.c中函数)

#ifndef __LCD1602_H__
#define __LCD1602_H__

//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

#endif

主文件:

#include <REGX52.H>
#include "LcD1602.h"

void main()
{
		LCD_Init();                           //初始化LCD
		LCD_ShowChar(1,1,'A');                //在第一行第一列显示“A”(字符串)
		LCD_ShowString(1,3,"Hello");          //从第一行第三列开始显示“Hello”(一个字母一格)
  		LCD_ShowNum(1,9,123,1);               //从第一行第九列开始显示“123”(只显示一位,最终显示“1”)
		LCD_ShowSignedNum(1,13,-66,2);        //从第一行第十三列开始显示“-66”(“-”占一位,最终显示“-66”)
		LCD_ShowHexNum(2,1,0xA8,2);
		LCD_ShowBinNum(2,4,0xAA,8);
		{
				
		}
}

实现效果:
请添加图片描述
小应用:

#include <REGX52.H>
#include "LcD1602.h"

int Result;

void main()
{
		LCD_Init();
		Result=1+1;
		LCD_ShowNum(1,1,Result,2);
		while(1)
		{
				
		}
}

显示结果:请添加图片描述

二、矩阵键盘

原理图:
在这里插入图片描述

2.1 简单使用

矩阵键盘又称为行列式键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。
在行线和列线的每一个交叉点上,设置一个按键。这样键盘中按键的个数是4×4个。
这种行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。由于单片机IO端口具有线与的功能,因此当任意一个按键按下时,行和列都有一根线被线与,通过运算就可以得出按键的坐标从而判断按键键值。

矩阵键盘,像是把独立按键和数码管杂糅在了一起?通过读取引脚变化引起的电平变化来扫描判断按键的位置。
矩阵键盘可以作用在数码管,作用在LCD,也可以作用在串口。下面我们以LCD为例介绍矩阵键盘的使用。

将按键与数值的互通进行模块化:

#include <REGX52.H>
#include "Delay1.h"

unsigned char MatrixKey()
{
		unsigned char KeyNumber=0;
	
		P1=0xFF;
		P1_3=0;
		if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
		if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
		if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
		if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	
		
		P1=0xFF;
		P1_2=0;
		if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
		if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
		if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
		if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
		
		P1=0xFF;
		P1_1=0;
		if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
		if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
		if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
		if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
		
		P1=0xFF;
		P1_0=0;
		if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
		if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
		if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
		if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
		
		return KeyNumber;
}

凭此,我们得到了MatrixKey.h
进行简单的调用:

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"

unsigned char KeyNum;    //定义全局变量KeyNum

void main()
{
		LCD_Init();
		LCD_ShowString(1,1,"MatrixKey:");
		while(1)
		{
				KeyNum=MatrixKey();        //将按键值赋予KeyNum
				if(KeyNum)
				{
						LCD_ShowNum(2,1,KeyNum,2);      //显示KeyNum
				}
		}
}

按下s12按键,结果如下:
请添加图片描述

2.2 制作简易的密码锁

代码如下:

#include <REGX52.H>
#include "Delay1.h"
#include "LCD1602.h"
#include "MatrixKey.h"

unsigned char KeyNum;
unsigned int Password,Count;     //定义密码、轮数

void main()
{
		LCD_Init();
		LCD_ShowString(1,1,"Password:");
		while(1)
		{
				KeyNum=MatrixKey();
				if(KeyNum)
				{
						if(KeyNum<=10)
						{
								if(Count<4)
								{
										Password*=10;      //密码左移
										Password+=KeyNum%10;  //获取密码
										Count++;
								}
								LCD_ShowNum(2,1,Password,4);
						}
						if(KeyNum==11)                     //判断正误
						{
								if(Password==2345)
								{
										LCD_ShowString(1,14,"OK ");
										Password=0;
										Count=0;
								}
								else
								{
										LCD_ShowString(1,14,"ERR");
										Password=0;
										Count=0;
								}
						}
						if(KeyNum==12)                           //取消
						{
								Password=0;
								Count=0;
								LCD_ShowNum(2,1,Password,4);   //更新显示
						}
				}
		}
}

结果如下:(以2345作为密码)
请添加图片描述

请添加图片描述

三、定时器

3.1 原理

本51单片机有三个定时器T0、T1与T2(可能有些单片机没有T1)。
定时器实质是加一计数器,大致框图如下:
在这里插入图片描述
当计数达到一定条件时,向中断系统发送中断申请,以执行定时任务。(最大可记到65535)

T0、T1定时器的工作模式均包括以下四种:
模式0(13位定时器)
模式1(16位定时器)(常用)
模式2(8位自动重装)
模式3(两个8位定时器)

在这里插入图片描述

上图为工作模式1的连接图:

SYSclk:系统时钟,即晶振周期。

中断系统

突然发生紧急情况,需要cpu停下当前任务去解决的情况叫做中断,这些引起中断的突发状况被称作中断源。一个中断系统可以有多个中断源,根据轻重缓急进行先后处理。如果cpu在处理一个中断源请求时,发生了一个优先级更高的请求,那么cpu会优先处理该请求,处理完再回到低级中断服务程序,这个过程被称作中断嵌套
没有中断嵌套系统的中断系统被称为单级中断系统,有的则称为多级中断系统
示意图:在这里插入图片描述
本单片机结构示意图:
在这里插入图片描述

中断资源:(与单片机型号相关)
中断源(8个):外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断、外部中断2、定时器2中断、外部中断3
中断优先级数:4
中断号:在这里插入图片描述

寄存器

寄存器是连接软硬件的媒介。
单片机通过配置寄存器来控制内部电路的连接,控制不同电路实现不同功能。

在这里插入图片描述
在这里插入图片描述
TCON:定时器/计时器T0、T1的控制寄存器。
在这里插入图片描述

TMOD:定时器/计时器的工作模式寄存器。
符号代表对应寄存器的状态,具体含义及功能可以说明书或网上查询。

3.2 小应用

定时器模块的代码可以通过stc-isp快速实现,不作过多说明。
如此配置,得到相应代码在这里插入图片描述
时钟6T模式可在应用左侧勾选。本版单片机时钟只有6T、12T两种模式,所以可以直接删去第一行代码:

void Timer0_Init(void)		//1毫秒@11.0592MHz
{
		TMOD &= 0xF0;			//设置定时器模式
		TMOD |= 0x01;			//设置定时器模式
		TL0 = 0x66;				//设置定时初始值
		TH0 = 0xFC;				//设置定时初始值
		TF0 = 0;				//清除TF0标志
		TR0 = 1;				//定时器0开始计时
		ET0 = 1;        //启用了定时器0的中断,当Timer0溢出会产生中断
		EA = 1;         //启用全局中断
		PT0 = 0;        //将定时器0设置为非倒计时模式。在倒计时模式下,当计数到零时,Timer0会自动重新加载初值并继续计数。设置为非倒计时模式后,需要手动重新加载初值以继续计数。
}

定时器控制流水灯

创建独立按键模块:

#include <REGX52.H>
#include "Delay.h"

/**
  * @brief    获取独立按键键码
  * @param     无
  * @retval   按下按键键码,范围:0~4,无按键按下时返回值为0
  */
unsigned char Key()
{
	  unsigned char KeyNumber=0;
		
		if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
		if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
		if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
		if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
		
		return KeyNumber;
}

正文:

#include <REGX52.H>
#include "Timer0.h"
#include "key.h"
#include <INTRINS.H>             //调用系统定义的函数模块_crol_、_cror_

unsigned char KeyNum,LEDMode;

void main()
{
		P2=0xFE;
   	Timer0_Init();
		while(1)
		{
				KeyNum=Key();
				if(KeyNum)
				{
						if(KeyNum==1)
						{
								LEDMode++;
								if(LEDMode>=2)
										LEDMode=0;
						}
				}
		}
}

void Timer0_Routine() interrupt 1
{
		static unsigned int T0Count;     //静态局部变量,防止变量值丢失
		TL0 = 0x66;				
		TH0 = 0xFC;
		T0Count++;
	  if(T0Count>=500)
		{
				T0Count=0;
				if(LEDMode==0)
					  P2=_crol_(P2,1);         //循环左移
				if(LEDMode==1)
						P2=_cror_(P2,1);         //循环右移
		}
}

至此,已实现流水灯和定时器的结合,按下第一个独立按键可以实现转向。

简易时钟

实现代码:

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Timer0.h"

unsigned char Sec,Min,Hour;

void main()
{
		LCD_Init();
		Timer0_Init();
		LCD_ShowString(1,1,"Clock:");
		LCD_ShowString(2,3,":");
		LCD_ShowString(2,6,":");                   //可写成LCD_ShowString("  :  :");
		while(1)
		{
				LCD_ShowNum(2,1,Hour,2);
				LCD_ShowNum(2,4,Min,2);
				LCD_ShowNum(2,7,Sec,2);
		}
}

void Timer0_Routine() interrupt 1      //中断函数
{
		static unsigned int T0Count;     //静态局部变量,防止变量值丢失
		TL0 = 0x66;				
		TH0 = 0xFC;
		T0Count++;
	  if(T0Count>=1000)
		{
				T0Count=0;
				Sec++;                          //中断函数一般只进行简单任务
				if(Sec>=60)
				{
						Sec=0;
						Min++;
						if(Min>=60)
						{
								Min=0;
								Hour++;
						}
				}
		}
}

效果:
请添加图片描述

四、串口

4.1 基本概念

串行通信与并行通信

串行通信是指使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。
在这里插入图片描述
并行通信通常是将数据字节的各位用多条数据线同时进行传送。
在这里插入图片描述
虽然,并行通信的效率高,传输速度快,但是要想实现同时接收十分困难。顾及成本与可行性,我们一般会选择串口通信。

串口是一种应用十分广泛的通讯接口,单片机的串口可以使其与单片机、电脑等各种模块相互通信。
51单片机内部自带UART,可实现单片机的串口通信。
串口连接:
在这里插入图片描述
模式图:
在这里插入图片描述

简单双向串口通信有两根通信线(发送端TXD与接收端RXD,可以不止两根),TXD与RXD要交叉连接。
如果只是单向的数据传输,可以直接连一根通信线。
当电平标准不一致,需要加电平转换芯片转换为一致标准。(强行传输会造成设备的损坏)

电平标准(数据1与数据0的表达方式)

常用的三种电平标准如下:
TTL电平:+5V表示1,0V表示0
RS232电平:-3 ~ -15V表示1,+3 ~ +15V表示0
RS485电平:两线压差+2~+6V表示1,-2 ~ -6V表示0(差分信号,传输距离长)

常见的通信接口:
在这里插入图片描述
以及CAN、USB等。

通信方式

(1)、单工通信
单工是指数据传输仅能沿一个方向,不能实现反向传输。
(2)、半双工通信
半双工是指数据传输可以沿两个方向,但需要分时进行。(复用一根数据线)
(3)、全双工通信
全双工是指数据可以同时进行双向传输。
(4)、异步通信
指通信双方各自约定通信速率
(5)、同步通信
通信双方靠一根时钟线来约定通信速率

本51单片机原理图:
在这里插入图片描述

寄存器

波特率:串口通信的速率(发送与接收各数据位的间隔时间)
检验位:用于数据验证
停止位:用于数据帧间隔
时序图:
在这里插入图片描述
串口相关寄存器:
在这里插入图片描述
其中,SCON为串口控制寄存器:
在这里插入图片描述
SMOD为电源控制寄存器:
在这里插入图片描述
SBUF为串口数据寄存器,还有TMOD等诸多寄存器,不一一展示。
代码,可以使用stc-isp的串口助手协助完成。
在这里插入图片描述

与中断系统

在这里插入图片描述
可以类比定时器。

4.2 简单任务

关于配置串口的代码,可以使用stc-isp进行编写:

在这里插入图片描述

void Uart1_Init(void)	//4800bps@11.0592MHz
{
	PCON |= 0x80;		//使能波特率倍速位SMOD
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器时钟12T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xF4;			//设置定时初始值
	TH1 = 0xF4;			//设置定时重载值
	ET1 = 0;			//禁止定时器中断
	TR1 = 1;			//定时器1开始计时
}

由于版本问题,AUXR没有被正确定义,可以删去。

串口向电脑传输数据

在这里插入图片描述

void UART_SendByte(unsigned char Byte)
{
		SBUF=Byte;             //写入数据
		while(TI==0);
		TI=0;                  //检查写入
}

完整代码(模块化前):

#include <REGX52.H>
#include "Delay.h"

unsigned char sec;

void Uart1_Init(void)	//4800bps@11.0592MHz
{
	PCON |= 0x80;		//使能波特率倍速位SMOD
	SCON = 0x50;		//8位数据,可变波特率
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xF4;			//设置定时初始值
	TH1 = 0xF4;			//设置定时重载值
	ET1 = 0;			//禁止定时器中断
	TR1 = 1;			//定时器1开始计时
}

void UART_SendByte(unsigned char Byte)
{
		SBUF=Byte;             //写入数据
		while(TI==0);
		TI=0;                  //检查写入
}

void main()
{
		Uart1_Init();
		while(1)
		{
				UART_SendByte(sec);
				sec++;
				Delay(1000);
		}
}

现象:
在这里插入图片描述

电脑通过串口控制LED

在这里插入图片描述
在这里插入图片描述

在串口传输模块中加入与中断系统的关联:

	EA=1;
	ES=1;

构造中断服务子函数:(中断号见3.1)

void UART_Routine() interrupt 4
{
		if(RI==1)
		{
				P2=~SBUF;
				UART_SendByte(SBUF);
				RI=0;
		}
}

代码如下:

#include <REGX52.H>
#include "Delay.h"
#include "UART.h"

void main()
{
		UART_Init();
		while(1)
		{
			
		}
}

void UART_Routine() interrupt 4
{
		if(RI==1)
		{
				P2=~SBUF;
				UART_SendByte(SBUF);
				RI=0;
		}
}

现象:
请添加图片描述
发送”11“:

在这里插入图片描述
请添加图片描述

五、LED点阵屏

本单片机原理图:
在这里插入图片描述

5.1 背景知识

点阵屏的结构类似数码管。(数码管就像其中的单元结构组成”8“字)
在这里插入图片描述
在这里插入图片描述

74HC595

74HC595是串行输入并行输出的移位寄存器,可用3根线输入串行数据,8根线输出并行数据。
在这里插入图片描述
常用于IO口扩展。

5.2 显示图形及动画

代码:

#include <REGX52.H>
#include "Delay.h"

sbit RCK=P3^5;    //RCLK
sbit SCK=P3^6;    //SRCLK
sbit SER=P3^4;    //SER

/**
  * @brief   74H595写入一个字节
  * @param	 Byte 要写入的字节
  * @retval  无
  */
void _74HC595_WriteByte(unsigned char Byte)
{
		unsigned char i;
		for(i=0;i<8;i++)
		{
				SER=Byte&(0x80>>i);
				SCK=1;
				SCK=0;
		}
		RCK=1;
		RCK=0;
}

/**
  * @brief   LED点阵屏显示一列数据
  * @param	 Column 要选择的列,范围:0~7,0在最左边
	* @param	 Data 选择列显示的数据,高位在上,1为亮,0为灭
  * @retval  无
  */
void MatrixLED_ShowColumn(unsigned char Column,Data)
{
		_74HC595_WriteByte(Data);
		P0=~(0x80>>Column);      
		Delay(1);	        //消位选与段选间的延时
		P0=0xFF;
}

void main()
{
		SCK=0;
		RCK=0;
		
		while(1)
		{
				MatrixLED_ShowColumn(0,0x3C);
				MatrixLED_ShowColumn(1,0x42);
				MatrixLED_ShowColumn(2,0xA9);
				MatrixLED_ShowColumn(3,0x85);
				MatrixLED_ShowColumn(4,0x85);
				MatrixLED_ShowColumn(5,0xA9);
				MatrixLED_ShowColumn(6,0x42);
				MatrixLED_ShowColumn(7,0x3C);
		}
}

可以显示一个笑脸:(拙劣的照相技术)
请添加图片描述
也可以显示流动的图形,可以适当使用工具。
在这里插入图片描述
通过文字取模工具得到想要的图案的代码数组。
实现流动的代码:

#include <REGX52.H>
#include "Delay.h"
#include "MatrixLED.h"

unsigned char Animation[]={
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0xFF,0x10,0x10,0x10,0xFF,0x07,0x78,0x90,0x78,0x07,0xFF,0x90,0x90,0x90,0x60,0xFF,
		0x90,0x90,0x90,0x60,0x80,0x40,0x3F,0x40,0x80,0x00,0xFF,0x91,0x91,0x91,0x6E,0x81,
		0xFF,0x81,0xFF,0x98,0x94,0x92,0x61,0x80,0x80,0xFF,0x80,0x80,0xFF,0x10,0x10,0x10,
		0xFF,0xFF,0x81,0x81,0x42,0x3C,0x07,0x78,0x90,0x78,0x07,0x80,0x40,0x3F,0x40,0x80,
};

void main()
{
		unsigned char i,Offset=3,Count=0;
		MatrixLED_Init();
		while(1)
		{
				for(i=0;i<8;i++)
				{
						MatrixLED_ShowColumn(i,Animation[i+Offset]);
				}
				Count++;
				if(Count>10)
				{
						Count=0;
						Offset++;
						if(Offset>72)     //数组元素数
						{
								Offset=0;
						}
				}
		}
}

可以得到流动的“HAPPY BIRTHDAY”。
请添加图片描述
P23-24后续再补

  • 18
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值