4、在STM32F103的基础上使用ATK-LORA-01

经过几天的努力和划水,终于在STM32F103的基础上使用ATK-LORA-01上的大部分功能,下一步就是进行LORA定位了,不过感觉还有一些自己觉得不完美的地方就是不能使用中断去选择AT模式还是通信模式,具体说就是通过按键中断,在AT模式和通信模式之间切换,遇到的技术难题是,在进入中断之后,运行中断完毕之后还会进入原来运行的地方,也就是说如果主程序在While循环中运行,中断之后,还是会进入while循环,除非在中断中找到条件使while循环跳出,但是在scanf函数重定义中有while循环,有那么一点点想法,但是现在又有其他的事情要去做,所以看看能不能下次解决这个问题!

在STM32F103的基础上使用ATK-LORA-01思绪图
在这里插入图片描述

代码部分

main函数中的代码不在展示,主要是各种初始化,以及LORA运行函数;

configure.h

#ifndef __CONFIGURE_H_
#define __CONFIGURE_H_

#include "stm32f1xx.h"
#include "stm32_types.h"
#include "stm32f1xx_hal.h"
#include "stdio.h"

#include "key.h"
#include "led.h"
#include "usart.h"


//*****************************************************这是一个无情的分割线************************************//
//********************************************************函数声明区*******************************************//

void LoRa_Configure_Init(void);    //初始化函数              

void LoRa_AT(void);                //AT模式还是通信模式      
void LoRa_Command(void);           //AT配置模式              

void LoRa_Query(void);             //配置查询                
void LoRa_ReQuery(void);           //是否重新查询            

void LoRa_Parameter(void);         //配置模式                       
void LoRa_Manual(void);            //手动配置                
void LoRa_Auto(void);              //自动配置               


void LoRa_Reset(void);             //模块复位                


void LoRa_Communication(void);     //通信模式                
void LoRa_Send(void);              //发送模式
void LoRa_Rsend(void);             //查询是否重新发送
void LoRa_Receive(void);           //接收模式 

#endif

configure.c

这里为了思路更加清晰我分为四个部分,变量声明,主体函数,AT模式和通信模式

变量声明

//******************************************这是一个无情的分割线*******************************//
//********************************************变量声明区***************************************//

char Baud[8][10] = {"1200","2400","4800","9600","19200","38400","57600","115200"};     //波特率
#define LoRa_Baud_1200     0       //1200                                                     
#define LoRa_Baud_2400     1       //2400
#define LoRa_Band_4800     2       //4800
#define LoRa_Band_9600     3       //9600
#define LoRa_Band_19200    4       //19200
#define LoRa_Band_38400    5       //38400
#define LoRa_Band_57600    6       //57600
#define LoRa_Band_115200   7       //11200



char Test[3][10] = {"无校验","偶校验","奇校验"};                                 //检验位
#define LoRa_Test_wu   0       //无校验
#define LoRa_Test_ou   1       //偶校验
#define LoRa_Test_ji   2       //奇校验



char aRate[6][10] = {"0.3","1.2","2.4","4.8","9.6","19.2"};                      //空中速率
#define LoRa_aRate_03   0       //0.3k
#define LoRa_aRate_12   1       //1.2k
#define LoRa_aRate_24   2       //2.4k
#define LoRa_aRate_48   3       //4.8k
#define LoRa_aRate_96   4       //9.6k
#define LoRa_aRate_192  5       //19.2k



char Sleep[2][5] = {"1","2"};                                                    //休眠时间
#define LoRa_Sleep_1  0        //1s
#define LoRa_Sleep_2  1        //2s


char Mode[4][15] = {"一般模式","唤醒模式","省电模式","信号强度模式"};            //工作模式
#define LoRa_Mode_common     0      //一般模式
#define LoRa_Mode_rouse      1      //唤醒模式
#define LoRa_Mode_save       2      //省电模式
#define LoRa_Mode_signal     3      //信号强度模式



char eRate[4][10] = {"11","14","17","20"};                                       //发射功率
#define LoRa_eRate_11     0         //11dBm
#define LoRa_eRate_14     1         //14dBm
#define LoRa_eRate_17     2         //17dBm
#define LoRa_eRate_20     3         //20dBm



char State[2][12] = {"透明传输","定向传输"};                                      //工作状态
#define LoRa_state_tp   0           //透明传输
#define LoRa_state_dt   1           //定向传输


typedef struct
{
	int baud;
	int test;
	int arate;
	int sleep;
	int addrh;
	int addrl;
	int channel;
	int erate;
	int mode;
	int state;
	
}LORA;

LORA lora =
{
	.baud = LoRa_Band_115200,
	.test = LoRa_Test_wu,
	.arate = LoRa_aRate_03,
	.sleep = LoRa_Sleep_1,
	.addrh = 0,
	.addrl = 17, 
	.channel = 23,
	.erate = 3,
	.mode = 0,
	.state = 0,
};

主体函数(初始化函数和选择AT模式还是通信模式)

//********************************************这是一个无情的分割线*****************************//
//***********************************************LoRa初始化函数*********************************//
int keyvalue;                  //按键值用来确定是AT模式还是通信模式
uint8_t LEDflag;               //用来选择是AT模式还是通信模式,目的只选择一次


void LoRa_Configure_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;

	__GPIOA_CLK_ENABLE(); //使能GPIOA时钟


	//GPIOC0/1初始化设置
	GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;              //LED对应IO口PD4 PD5
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;    //普通推挽输出模式
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;  //高速
	GPIO_InitStruct.Pull = GPIO_NOPULL;            //上拉
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);        //初始化GPIO
	
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
	//LEDflag = 1;
	//默认为AT模式
}

//在这里MD0为PA4  AUX为PA5
void LoRa_AT(void)
{
	  keyvalue = Key_read();
	  if(keyvalue == 1)
		{
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);

			LEDflag = 1;
			keyvalue = 0;
		}
		
		 if(keyvalue == 2)
		{
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
			LEDflag = 2;
			keyvalue = 0;
		}
		
		if((LEDflag==1)&&(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == 1)&&(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5) == 0))
		{
			  printf("进入配置模式!!!\r\n\r\n");
			  LED_Open(1);
			  LED_Close(2);
			  LEDflag = 0;
			  LoRa_Command();
				
		}
		
		else if((LEDflag==2)&&(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == 0)&&(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5) == 0))
		{
			  printf("进入通信模式!!!\r\n\r\n");
			  LED_Open(2);
			  LED_Close(1);
			  LEDflag = 0;
			  LoRa_Communication();
		}
		 
}

LoRa查询函数(配置查询,参数设置 和模块复位)

//********************************************这是一个无情的分割线*****************************//
//************************************************LoRa查询函数*********************************//

char loraquery[7][15] ={"AT+WLRATE?\r\n","AT+UART?\r\n","AT+WLTIME?\r\n","AT+TPOWER?\r\n","AT+CWMODE?\r\n","AT+TMODE?\r\n","AT+ADDR?\r\n"};

void LoRa_Command(void)
{
	
	char order;
	char oflag = 1;
	printf("1、配置查询\r\n");
	printf("2、参数设置\r\n");
	printf("3、模块复位\r\n");
	printf("4、退出AT模式\r\n\r\n");
	
	//输入选择功能
	while(oflag)
	{
		scanf("%c",&order); 
		if(order ==10 ||order ==13)
		{
			oflag = 1;
		}
		else
		{
			oflag = 0;
		}
	}
	if(order != 10||order != 13)
	{
		getchar();
	}
	
	
	//三个选择功能
	if(order == '1')
	{
		LoRa_Query();
		order = '5'; 
		
	}
	else if(order == '2')
	{
		  printf("进入参数设置\r\n\r\n");
      LoRa_Parameter();
		
		  order = '5'; 
	}
	else if(order == '3')
	{
		printf("进入模块复位\r\n\r\n");
		LoRa_Reset();
		order = '5'; 
	}
	else if(order == '4')
	{
		printf("\r\n退出AT模式,请根据按键选择AT模式还是通信模式\r\n\r\n");
		order = '5'; 
	}
	
	
}


void LoRa_Query(void)
{
	  int i;
		printf("进入配置查询......\r\n");
		for(i=0;i<7;i++)
		{
		  USART2_send(loraquery[i]);
		  USART2_receive();
		  //这里可以加入汉字说明,先省略
		}
		LoRa_ReQuery();
}

void LoRa_ReQuery(void)
{
	char data[20];
	printf("是否重新进入配置查询(yes/no)...\r\n");
	scanf("%s",data);
	if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
	{
			LoRa_Query();
  }
	else
	{
			printf("\r\n退出配置查询模式,请根据按键选择AT模式还是通信模式\r\n\r\n");
		  getchar();
	} 
	
	
}

//********************************************这是一个无情的分割线*****************************//
//************************************************LoRa配置函数*********************************//

void LoRa_Parameter(void)
{
	 char order2;                   //用来判断是手动模式还是自动模式
	 
	
	 char oflag = 1;
	
	
	 printf("1、 手动配置\r\n");
	 printf("2、 自动配置\r\n\r\n");
	 printf("3、 退出配置配置\r\n\r\n");
	
	//选择功能
	 	while(oflag)
	{
		scanf("%c",&order2); 
		if(order2 ==10 ||order2 ==13)
		{
			oflag = 1;
		}
		else
		{
			oflag = 0;
		}
	}
	if(order2 != 10||order2 != 13)
	{
		getchar();
	}
	
	  
	 //手动配置
	 if(order2 == '1')
	 {
		  LoRa_Manual();
		  order2 = 0;
	 }
	 
	 //自动配置
	 if(order2 == '2')
	 {
     LoRa_Auto();
		 order2 = 0;
	 }
	 
	 //退出配置模式
	 if(order2 == '3')
	 {
		 order2 = 0;
	 }
	 
}


//手动配置函数
void LoRa_Manual(void)
{
	 char data[20];                       //用来存储指令
	 char order3 = '1';                   //用来判断手动模式是否继续输入
	 printf("进入手动配置...\r\n");
	
		 while(order3 == '1')
		 {

			 printf("请输入AT指令...\r\n");
			 scanf("%s",data);
			 sprintf(data,"%s\r\n",data);  //这里有个坑
			
			 USART2_send(data);
			 USART2_receive();  
			 
			 
			 printf("是否继续输入(yes/no)...\r\n\r\n");
			 scanf("%s",data);
			 //printf("%s",data);//
			 if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
			 {
				 order3 = '1';
			 }
			 else
			 {
				 order3 = '0';
			 } 
		 }
		 printf("\r\n退出手动配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
		 getchar();
		
}


//自动配置函数
void LoRa_Auto(void)
{    
	   int i;
	   char data[20];
	   char order4 = '1';
	   printf("进入自动配置...\r\n\r\n");
	   
	  
		 
			 
			 
   //*********波特率和校验位设置*****************//
	
	
	   while(order4 == '1')                //有待优化  可以选择设置
		 {
			
			 printf("请输入波特率...(1200、2400、4800、9600、19200、38400、57600、115200)\r\n");      
			 scanf("%s",data);
			 printf("%s\r\n\r\n",data);
			 
			 for(i=0;i<8;i++)
			 {
				 if(strcmp(data,Baud[i])==0)
				 {
					 lora.baud = i;
					 break;
				 }
			 }
			 
			 if(i<8)
			 {
				 
			 }
			 else
			 {
				   goto CuoWu;
			 }
			 
			 printf("请输入校验位(无校验/奇校验/偶校验)...\r\n");
			 scanf("%s",data);
			 printf("%s\r\n\r\n",data);
			 
			 for(i=0;i<3;i++)
			 {
				 if(strcmp(data,Test[i])==0)
				 {
					 lora.test = i;
					  break;
				 }
			 }
			 
			 if(i<3)
			 {
			   sprintf(data,"AT+UART=%d,%d\r\n",lora.baud,lora.test);
			   USART2_send(data);
			   USART2_receive();
				 order4 = '0';
				 printf("\r\n退出波特率和校验位配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
			 }
			
			 else
			 {
				 
	 CuoWu: printf("输入格式错误,是否重新输入....\r\n");
				  scanf("%s",data);
			 
			   if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
			   {
				   order4 = '1';
			   }
         else
			   {
				   order4 = '0';
					 printf("\r\n退出波特率和校验位配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
			   } 
			 }
		 }
			 
	 //*********信道和空中速率设置*****************//
	 
	     order4 = '1';
	     while(order4 == '1')
			 {
				 
			   printf("请输入信道(0-31)...\r\n");
			   scanf("%d",&lora.channel);
			   printf("%d\r\n\r\n",lora.channel);
			   printf("请输入空中速率(0.3、1.2、2.4、4.8、9.6、19.2)K...\r\n");
			   scanf("%s",data);
			   printf("%s\r\n\r\n",data);
				 
			   for(i=0;i<6;i++)
			   {
				   if(strcmp(data,aRate[i])==0)
				   {
					   lora.arate = i;
					   break;
				   }
			   }
				 
			   if(i<6)
			   {
				 
			     sprintf(data,"AT+WLRATE=%d,%d\r\n",lora.channel,lora.arate);
			     USART2_send(data);
			     USART2_receive(); 
           order4 = '0';
			     printf("\r\n退出信道和空中速率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
			   }
				 
			   else
			   {
				    printf("输入格式错误,是否重新输入....\r\n");
				    scanf("%s",data);
			 
			      if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
			      {
				       order4 = '1';
			      }
						
            else
			      {
				       order4 = '0';
					     printf("\r\n退出信道和空中速率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
			      } 
			   }
		   
			 }


//   //**************休眠时间设置*****************//
	      
			 order4 = '1';
			 while(order4 == '1')
			 {
					 printf("请输入休眠时间(1、2)s...\r\n");
					 scanf("%s",data);
					 printf("%s\r\n\r\n",data);
				 
					 for(i=0;i<3;i++)
					 {
							if(strcmp(data,Sleep[i])==0)
							{
								 lora.sleep = i;
								 break;
							}
					 }
					 
					 if(i<3)
					 {
							 sprintf(data,"AT+WLTIME=%d\r\n",lora.sleep);
							 USART2_send(data);
							 USART2_receive(); 
							 order4 = '0';
							 printf("\r\n退出休眠时间配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
					 }
					 
					 else
					 {
						    printf("输入格式错误,是否重新输入....\r\n");
								scanf("%s",data);
					 
								if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
								{
									 order4 = '1';
								}
								
								else
								{
									 order4 = '0';
									 printf("\r\n退出休眠时间配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
								} 
					 }

		   }

   //**************模块地址设置*****************//
	    
			
	   
			  printf("请输入模块地址(FF,00)...\r\n");
		    scanf("%s",data);
		    printf("%s\r\n\r\n",data);
			 
		    sprintf(data,"AT+ADDR=%c%c,%c%c\r\n",data[0],data[1],data[3],data[4]);
		    USART2_send(data);
  	    USART2_receive(); 
			  order4 = '1';
			

        
//		 
//   //**************发射功率配置*****************//
	     
			 while(order4 == '1')
			 {
						printf("请输入发射功率(11,14,17,20)dbm...\r\n");
						scanf("%s",data);
						printf("%s\r\n\r\n",data);
						for(i=0;i<4;i++)
						{
							 if(strcmp(data,eRate[i])==0)
							 {
									lora.erate = i;
									break;
							 }
						}
						
						if(i<4)
						{
							 sprintf(data,"AT+TPOWER=%d\r\n",lora.erate);
							 USART2_send(data);
							 USART2_receive(); 
							
							 order4 = '0';
							 printf("\r\n退出发射功率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
						}
						 
						 
						else
			      {
								printf("输入格式错误,是否重新输入....\r\n");
								scanf("%s",data);
						 
								if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
								{
										order4 = '1';
								}
									
								else
								{
										order4 = '0';
										printf("\r\n退出发射功率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
								} 
			      }
		  }

  
//    //*************工作模式设置*****************//

       order4 = '1';
		   while(order4 == '1')
			 {
           printf("请输入工作模式...(一般模式、唤醒模式、省电模式、信号强度模式)\r\n");
      	   scanf("%s",data);
			     printf("%s\r\n\r\n",data);
				 
					 for(i=0;i<4;i++)
					 {
						  if(strcmp(data,Mode[i])==0)
						  {
							 lora.mode = i;
							 break;
						  }			
					 }
					 
					if(i<4)
					{
							sprintf(data,"AT+CWMODE=%d\r\n",lora.mode);
							USART2_send(data);
							USART2_receive(); 
					  	order4 = '0';
					}
				  else
				  {
							printf("输入格式错误,是否重新输入....\r\n");
							scanf("%s",data);
				 
							if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
							{
								 order4 = '1';
							}
							
							else
							{
								 order4 = '0';
								 printf("\r\n退出发射功率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
							} 
				  }
		   }

//    //*************发送状态设置*****************//
			   order4 = '1';
         while(order4 == '1')
			   {
						printf("请输入发送状态...(透明传输、定向传输)\r\n");
						scanf("%s",data);
						printf("%s\r\n\r\n",data);
					 
						for(i=0;i<2;i++)
						{
							 if(strcmp(data,State[i])==0)
							 {
									 lora.state = i;
									 break;
							 }
						}
						
					  if(i<2)
					  {
								 sprintf(data,"AT+CWMODE=%d\r\n",lora.state);
								 USART2_send(data);
								 USART2_receive();
								 order4 = '0';
								 printf("\r\n退出发射功率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
					  }
						else
						{
							printf("输入格式错误,是否重新输入....\r\n");
							scanf("%s",data);
				 
							if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
							{
								 order4 = '1';
							}
							
							else
							{
								 order4 = '0';
								 printf("\r\n退出发射功率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
							} 
						}
				 }
        				
		
	   
}

//********************************************这是一个无情的分割线*****************************//
//************************************************LoRa模块复位*********************************//

void LoRa_Reset(void)
{
	 char data[20];
	 sprintf(data,"AT+RESET\r\n");
	 USART2_send(data);
   USART2_receive();
	 printf("模块复位完成!!!\r\n");
	 printf("\r\n退出模块复位配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}  

LoRa通信模块(接收模式,发送模式)

void LoRa_Communication(void)
{
	
	char order;
	char oflag = 1;
	printf("1、发送模式\r\n");
	printf("2、接收模式\r\n");
	printf("3、退出通信模式\r\n\r\n");
	
	//输入选择功能
	while(oflag)
	{
		scanf("%c",&order); 
		if(order ==10 ||order ==13)
		{
			oflag = 1;
		}
		else
		{
			oflag = 0;
		}
	}
	if(order != 10||order != 13)
	{
		getchar();
	}
	
	
	//三个选择功能
	if(order == '1')
	{
		LoRa_Send();
		order = '5'; 
		
	}
	
	else if(order == '2')
	{
		  LoRa_Receive();  
		  order = '5'; 
	}
	
	else if(order == '3')
	{
		  printf("\r\n退出通信模式,请根据按键选择AT模式还是通信模式\r\n\r\n");
		  order = '5'; 
	}
	 
}

//********************************************这是一个无情的分割线*****************************//
//************************************************LoRa发送模式*********************************//

void LoRa_Send(void)
{
			char *p = NULL;
			char data[100];
			printf("进入发送模式...\r\n");
			
			
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
			delay_ms(10);
			
			sprintf(data,"AT+TMODE?\r\n");
			USART2_send(data);
			USART2_receive();
			p  = USART2_Receive();

			printf("发送状态是: %s\r\n\r\n",State[p[18]-'0']);
	
			while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) != 0&&HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) != 0)
			{
				
				HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
				HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
			}
	
			if((p[18]-'0') == 0)
			{
				printf("请输入要发送的数据...\r\n\r\n");
				scanf("%s",data);	
			}
			else
			{
				printf("请输入要发送的数据(高位地址+低位地址+信道+用户数据)...\r\n");
				scanf("%s",data);
			}
			
			  delay_ms(10);
				printf("%s\r\n",data);
				sprintf(data,"%s\r\n",data);
				USART2_send(data);
				delay_ms(10);
				USART2_receive();
			  getchar();
			  LoRa_Rsend();

}



void LoRa_Rsend(void)
{
	char data[10];
	printf("\r\n是否重新进入发送模式(yes/no)...\r\n");
	scanf("%s",data);
	if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
	{
			LoRa_Send();
  }
	else
	{
		printf("\r\n退出发送模式,请根据按键选择AT模式还是通信模式\r\n\r\n");
		getchar();
	} 
}

//********************************************这是一个无情的分割线*****************************//
//************************************************LoRa接收*********************************//

void LoRa_Receive(void)
{
	  int rflag = 1;
	 
		printf("进入接收模式...\r\n");
	  printf("可以根据按键3退出接收模式\r\n\r\n");
	  
	  while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) != 0&&HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) != 0)
		{
				
	  	 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
			 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
		}
		
		while(rflag == 1)
		{
			keyvalue = Key_read();
			USART2_receive();
			if(keyvalue == 3)
			{
				rflag = 0;
				printf("\r\n退出接收模式,请根据按键选择AT模式还是通信模式\r\n\r\n");
			}
		}
	 
}
  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值