蓝牙小车

概要

  建立在51单片机以及stm32f4单片机上的蓝牙小车,它真的只是一台车没有什么别的功能。(主要原因是我太菜了)

硬件

淘宝搜索
1.蓝牙小车底盘。
2. l298n驱动两个。
3. 51单片机最小核心板。
4. STM32F4核心板。
5. 杜邦线一大堆。
6. 口香糖电池。

51单片机学习过程

买了一本郭天祥老师的51单片机教程以及一块学习板,配合着b站上的教程看,主要是为了初步了解入门单片机。怎么说呢,学习起来还是有点感悟的。

  1. 开始我是对照着书本进行学习,然后学了怎么操作自己试了一下之后就直接下一章节了,没有得到充分的练习,以至于真正做车车的时候发现有很多东西稀里糊涂的,得翻书重新查。这里的教训就是,学以致用很重要,理论-实践-理论的三明治原理。(后来发现郭天祥老师的视频里留有充足的课后练习)
  2. 其次就是中间中断了一段时间没有学习,大学生活丰富多彩嘛嘻嘻。。。没人管就很容易滋生堕落的情绪,所以说拥有坚定的信念很重要。

32单片机学习过程

这个就更加曲折了。。一开始看这个32的代码,简直是看天书一样,以至于出现什么一周快速学习stm32从入门到放弃再到不行还是得学之类的事情。

  1. 没有充分吸取51单片机的学习教训,也是了解差不多就直接下一章了。因为一个是时间紧迫,一个是因为现阶段没有学习学长学姐们口中的《微机原理》balabala…的书,就只能学会这个单片机怎么用,基本的使用原理大概是怎么个回事,实在没法特别深入地学习。
  2. 发现学习东西啊还是多看看视频,不要闷声看书,有人讲课的效果比自己慢慢慢慢看书的效果更好,书本可以作为对课堂细节的补充,而课堂却可以快速令人掌握一件事物的基本框架。
  3. 总的来说这次是一次有意义的学习体验,入门一件事情首先先了解框架(51单片机),再通过视频巩固框架(stm32的视频),书本补充细节,然后实践实践再实践,过程中的问题及时问前辈,不要闭门造车,有时候学长的一句提醒顶得上自己翻阅两天的资料。

51的程序

#include<reg52.h>

sbit IN1=P1^0; 
sbit IN2=P1^1;
sbit IN3=P1^2;
sbit IN4=P1^3;
sbit IN11=P1^4; 
sbit IN22=P1^5;
sbit IN33=P1^6;
sbit IN44=P1^7;


void Left_moto_go()      {IN1=0,IN2=1,IN11=0,IN22=1;}           //小车运动的正反转电平设置
void Left_moto_back()    {IN1=1,IN2=0,IN11=1,IN22=0;}         
void Left_moto_Stop()    {IN1=0,IN2=0,IN11=0,IN22=0;}                       
void Right_moto_go()     {IN3=0,IN4=1,IN33=0,IN44=1;}        
void Right_moto_back()   {IN3=1,IN4=0,IN33=1,IN44=0;}        
void Right_moto_Stop()   {IN3=0,IN4=0,IN33=0,IN44=0;}         

unsigned char  mode;  //用字符来作为运行的指令
unsigned  int  flag;

void delay(unsigned int k)
{    
  unsigned int x,y;
  for(x=0;x<k;x++) 
  for(y=0;y<2000;y++);
}


     void  TIME1()   //        选择使用定时器1;
{
         TMOD=0x20;                        //并且工作模式2,8位
         TH1=0xfd;                //产生9600波特率,与蓝牙模块同步 ,因为当时购买的蓝牙模块出厂设置就是9600波特率。
         TL1=0xfd;
         SM0=0;                   //设置串口的工作模式为
         SM1=1;                           //传送8位数据
         REN=1;                           //串口通信允许接收
         TR1=1;                           //开定时器1
         EA=1;                           //允许总中断
         ES=1;                           //允许串口中断
}
int main()
{
  TIME1();
  
  while(1)
 {
     if(flag)
     {
	   ES=0;               //这里一定要清零,不然下一个周期定时器中断就没法判断是否接收到信息了
	   
        if(mode=='1')        //这里采用数字作为通信          
        {  
		                     
         Left_moto_go() ;   
         Right_moto_go() ;   
         delay(20); //延时函数一定要有。
        }
        if(mode=='3') 
        {
         Left_moto_back();   
         Right_moto_back();	   //back
         delay(20);
        }
        if(mode=='4')
        {
	     Right_moto_go(); 
         Left_moto_Stop();     //left
         delay(10);	
        }
        if(mode=='5')
        {
          Left_moto_go();  
         Right_moto_Stop();    //right
         delay(10);
        }
       if(mode=='2')
        {
		 Right_moto_Stop();  
         Left_moto_Stop();  
         delay(40);			   //stop
	    }
	    ES=1;
	   flag=0;
     }
 }
}

void ser() interrupt 4
{
	RI=0;		    //接收中断标志
	mode=SBUF;		  //将接收到的手机发送到缓冲区数据SBUF复制给mode
	flag=1;    			   //说明已经接收数据完毕

}

这里比较简单,没有写pwm功能,将在stm32中使用pwm功能。

32单片机

这个花费了比较多的时间,一开始觉得天书,后来慢慢入门发现很多东西前人已经写好了,只要掌握使用的技巧就好了(毕竟我没有足够的专业知识,也不是搞弱电的)所以整个程序是建立在蓝牙模块的程序基础上写的。

主函数

#include "sys.h"
#include "delay.h"  
#include "usart.h"  
#include "led.h"
#include "pwm.h"
#include "usmart.h"		
#include "hc05.h" 	 
#include "usart3.h" 	
#include "string.h"	 

int main(void)
{ 
    u16 pwmval=1; 
	u16 speedlost=1; //转弯的时候用
	u16 dang=1;
	u8 reclen=0;  //检测获取数据
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);      //初始化延时函数
	uart_init(115200);		//初始化串口波特率为115200
	TIM2_PWM_Init(500-1,84-1);	//84M/84=1Mhz的计数频率,重装载值500,所以PWM频率为 1M/500=2Khz.
	TIM3_PWM_Init(500-1,84-1);
	TIM9_PWM_Init(500-1,84-1);
	usmart_dev.init(84); 		//初始化USMART		
	LED_Init();					//初始化LED
	delay_ms(1000);			//等待蓝牙模块上电稳定
 	HC05_Init();		//初始化ATK-HC05模块  
	 										   	   
	delay_ms(100);
	USART3_RX_STA=0;
	
 	while(1) 
	{		

		LED0=!LED0; 	     
	 
		if(USART3_RX_STA&0X8000)			//接收到一次数据了
		{
 			reclen=USART3_RX_STA&0X7FFF;	//得到数据长度
		  	USART3_RX_BUF[reclen]=0;	 	//加入结束符
			if(reclen!=0) 		//控制DS1检测
			{
				
				if(strcmp((const char*)USART3_RX_BUF,"+SPEED1")==0)  
				 //设置挡位    //必须以+开头才可以啊!
				{ 
				 delay_ms(1);
                 LED1=!LED1;					
                 pwmval=1;
				 dang=1;
				}
				if(strcmp((const char*)USART3_RX_BUF,"+SPEED2")==0)
				{
				 delay_ms(1);	
                 LED1=!LED1;					
                 pwmval=100;
				 dang=100;
				}
				if(strcmp((const char*)USART3_RX_BUF,"+SPEED3")==0)
				{ 
				delay_ms(1);	
                LED1=!LED1;					
                pwmval=200;
				dang=200;
				}                                                          
				
				
				if(strcmp((const char*)USART3_RX_BUF,"+FORWARD")==0)   
               { 
					LED1=!LED1;//测试用的,到时候可以删掉
					TIM_SetCompare1(TIM9,pwmval);  //右边两个轮子分别接一个PE5,PE6
					TIM_SetCompare2(TIM9,pwmval);
					TIM_SetCompare1(TIM2,pwmval);  //左边两个轮子分别接一个PA0,PA1
					TIM_SetCompare2(TIM2,pwmval); 
					delay_ms(500);
				}				
				
				if(strcmp((const char*)USART3_RX_BUF,"+BACK")==0)   
               { 
					LED1=!LED1;
					TIM_SetCompare1(TIM3,pwmval);  //右边两个轮子分别接一个PC6789
					TIM_SetCompare2(TIM3,pwmval);
					TIM_SetCompare3(TIM3,pwmval);
					TIM_SetCompare4(TIM3,pwmval);
					delay_ms(500);
					
				}			
				
				
				if(strcmp((const char*)USART3_RX_BUF,"+RIGHT")==0)   
               { 
					LED1=!LED1;
					speedlost=pwmval+100;
					TIM_SetCompare1(TIM9,speedlost);  //右边两个轮子分别接一个PE5,PE6   //右边轮子变慢
					TIM_SetCompare2(TIM9,speedlost);
					TIM_SetCompare1(TIM2,pwmval);  //左边两个轮子分别接一个PA0,PA1
					TIM_SetCompare2(TIM2,pwmval); 
					delay_ms(500);
				}	
				
				
				if(strcmp((const char*)USART3_RX_BUF,"+LEFT")==0)   
               { 
					speedlost=pwmval+100;
					LED1=!LED1;//测试用的,到时候可以删掉
					TIM_SetCompare1(TIM9,pwmval);  //右边两个轮子分别接一个PE5,PE6
					TIM_SetCompare2(TIM9,pwmval); 
					TIM_SetCompare1(TIM2,speedlost);  //左边两个轮子分别接一个PA0,PA1  //左边轮子变慢
					TIM_SetCompare2(TIM2,speedlost); 
					delay_ms(500);
				}
				
             	if(strcmp((const char*)USART3_RX_BUF,"+STOP")==0)   
              { 
					LED1=!LED1;  //测试用的,到时候可以删掉
					pwmval=500;
					TIM_SetCompare1(TIM9,pwmval);  //右边两个轮子分别接一个PE5,PE6
					TIM_SetCompare2(TIM9,pwmval);
					TIM_SetCompare1(TIM2,pwmval);  //左边两个轮子分别接一个PA0,PA1
					TIM_SetCompare2(TIM2,pwmval);
					TIM_SetCompare1(TIM3,pwmval);  //右边两个轮子分别接一个PC6789
					TIM_SetCompare2(TIM3,pwmval);
					TIM_SetCompare3(TIM3,pwmval);
					TIM_SetCompare4(TIM3,pwmval);                                    //全部停下
					delay_ms(500);
					pwmval=dang;
				}				
	
			}
 			
 			USART3_RX_STA=0;	 
		}	 															     				   
		
	}											    
}



pwm函数

#include "pwm.h"
#include "led.h"
#include "usart.h"
 
//TIM4 PWM部分初始化 
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u32 arr,u32 psc)
{		 					 
	//此部分需手动修改IO口设置
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  	//TIM3时钟使能    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); 	//使能PORTC
	
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM4); //GPIOC6复用为定时器3
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM4);
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM4);
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM4);
	
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;           //GPIOC6
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOC,&GPIO_InitStructure);              //初始化PC6
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;           //GPIOC7
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOC,&GPIO_InitStructure);              //初始化PC7
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;           //GPIOC8
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOC,&GPIO_InitStructure);              //初始化PC8
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOC9
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOC,&GPIO_InitStructure);              //初始化PC9
	  
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//初始化定时器3
	
	//初始化TIM3 Channel 6789 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 4OC1
	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 4OC1
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器
	TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 4OC1
	TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器
	TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 4OC1
	TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器
  
  TIM_ARRPreloadConfig(TIM3,ENABLE);//ARPE使能 
	
	TIM_Cmd(TIM3, ENABLE);  //使能TIM3
 
										  
}  

void TIM2_PWM_Init(u32 arr,u32 psc)
{		 					 
	//此部分需手动修改IO口设置
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);  	//TIM2时钟使能    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 	//使能PORTA
	
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM2); //GPIOA0复用为定时器2
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM2); //GPIOA1复用为定时器2
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure);              //初始化PA0
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;  
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure);              //初始化PA1
	  
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);//初始化定时器2
	
	//初始化TIM2 Channel 12 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 4OC1
	TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR1上的预装载寄存器
	TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 4OC2
	TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR2上的预装载寄存器

  
  TIM_ARRPreloadConfig(TIM2,ENABLE);//ARPE使能 
	
	TIM_Cmd(TIM2, ENABLE);  //使能TIM2
 
										  
}  


void TIM9_PWM_Init(u32 arr,u32 psc)
{		 					 
	//此部分需手动修改IO口设置
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9,ENABLE);  	//TIM9时钟使能    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); 	//使能PORTE
	
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource5,GPIO_AF_TIM9); //GPIOE5复用为定时器9
	GPIO_PinAFConfig(GPIOE,GPIO_PinSource6,GPIO_AF_TIM9); //GPIOE6复用为定时器9
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;           //GPIOE5 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOE,&GPIO_InitStructure);              //初始化PE5/6
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;           //GPIOE6	 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOE,&GPIO_InitStructure);              //初始化PE6
	  
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM9,&TIM_TimeBaseStructure);//初始化定时器9
	
	//初始化TIM9 Channel 12 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
	TIM_OC1Init(TIM9, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM9 4OC1
	TIM_OC1PreloadConfig(TIM9, TIM_OCPreload_Enable);  //使能TIM9在CCR1上的预装载寄存器
	TIM_OC2Init(TIM9, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM9 4OC2
	TIM_OC2PreloadConfig(TIM9, TIM_OCPreload_Enable);  //使能TIM9在CCR2上的预装载寄存器
    TIM_ARRPreloadConfig(TIM9,ENABLE);//ARPE使能 	
	TIM_Cmd(TIM9, ENABLE);  //使能TIM2
 }  

这里之所以调用这么多定时器,是因为另外的几个定时器被项目的其他功能占用了。
这里就只放两个主要的函数吧,蓝牙和其他函数的代码放在总的程序目录里。(懒得拷贝了。。。)

硬件连接

原理图(啊别吐槽我灵魂画手了)
在这里插入图片描述

这里只上传51的连接
调用了

视频截图。。。
在这里插入图片描述

在这里插入图片描述

恭喜你司机同志,秋名山一较高下。

最后

再次感谢教我搭建博客,教我做车车,教我开车车的学长学姐。希望自己大学四年能开个好头,继续学习哈。(不说了昨天C语言上机跪了(手动哭泣),得赶紧复习高数把分数捞回来才行。。。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值