基于Lora实现的屋内火灾报警系统

1.功能设计

  本项目设计一种基于LORA无线通信的屋内火灾报警控制系统,采用DH11温湿度传感器跟MQ-2烟雾传感器作为火警安防系统,对房内温度,湿度,还有环境可燃气体,烟雾等实时检测,LORA通信为通信报警方法,LED跟蜂鸣器为声光报警,SG90舵机做为应急措施的开关。当温度湿度传感部分采集到超过限定温度值和低于限定湿度值时,会将信号发给相对应的传感检测部分,然后传感检测部分将信号发给核心处理器单片机,STM32F103RCT6核心处理单片机引脚电平转换,驱动声光报警系统和应急措施,同时启动LORA通信发送给业主和物业,让救援人员来时了解到大致情况做好充足准备。

 (1) 检测项目:当环境温度≥45℃,湿度≤10%就可被判定为火灾,或者可燃气体甲烷浓度≥5%也可被判定为火灾可能发生,实施报警,并且采取应急措施。烟雾浓度≥5%被认定为有毒害,实施报警。

 

(2) 报警方式:声光报警,小区物业报警,户主报警。

(3) 应急措施:通过舵机控制阻燃气体的发射。

2.硬件设计

  本系统由电源电路、主控制器、温度,湿度检测电路、烟雾可燃气体检测电路,LORA模块收发电路,应急措施电路,信息显示电路,声光报警电路等8个部分组成。

 

3.软件设计

 

 

其余介绍看,评论区报告链接,硬件设备工作流程图,以及步骤介绍等等。。。

程序分享

1.main.c

#include "led.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "dh11.h"   
#include "adc.h"  
#include "sys.h"
#include "delay.h"
#include "pwm.h"
#include "beep.h"
#include "lora.h"
#include "usart1.h"
#include "usart3.h"
char lora_tx_data[100];
char lora_rx_data[100];
 int main(void)
 { 
	u16 ADC_SHIDU ;
	u8 t=0;			 
	u8 temp;   
	u8 humi;
	 
	delay_init();	    	 //延时函数初始化	  
  Adc_Init();   	 //延时函数初始化	  
	uart_init(115200);	 	//串口初始化为9600
	LED_Init();		  		//初始化与LED连接的硬件接口
 	LCD_Init();
	Beep_Init();//蜂鸣器初始化 
  SystemInit();	//配置系统时钟为 72M  
	USART1_Config();
	TIM3_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz 
	USART3_Config(115200); //USART3 配置 		
	LORA_Init();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	 
	 
 	POINT_COLOR=BLUE;//设置字体为蓝色 
	LCD_ShowString(60,50,200,16,16,"GHB");	
	LCD_ShowString(60,70,200,16,16,"GXW");	
	LCD_ShowString(60,90,200,16,16,"LX");
	LCD_ShowString(60,110,200,16,16,"2021/12/6");		  
	LCD_ShowString(60,130,200,16,16,"DHT11 OK");
	LCD_ShowString(60,150,200,16,16,"QCM2  OK");
	POINT_COLOR=BLUE;//设置字体为蓝色 
 	LCD_ShowString(60,170,200,16,16,"Temp:   . C");	 
	LCD_ShowString(60,190,200,16,16,"Humi:   %");	 
	LCD_ShowString(60,210,200,16,16,"Qtzl:   %");
	

	while(DHT11_Init())	//DHT11初始化	
	{
		LCD_ShowString(60,130,200,16,16,"DHT11 Error");
		delay_ms(200);
		LCD_Fill(60,130,239,130+16,WHITE);
 		delay_ms(200);
	}								   
	while(1)
	{	    	   
   ADC_SHIDU=ADC_Get_aveg(ADC_Channel_1,10);
	 ADC_SHIDU = (float)(ADC_SHIDU/4096.0)*100;   

		{		
			
       DHT11_Read_Data(&temp,&humi);	//读取温湿度值	
       LCD_ShowNum(60+40+4,170,temp,2,16);	//显示温度		
       LCD_ShowNum(60+40+28,170,temp%10,1,16);	//显示温度				
	     LCD_ShowNum(60+40+6,190,humi,2,16);		//显示湿度	 			
       LCD_ShowNum(60+40+6,210,ADC_SHIDU,2,16);	
				delay_ms(100);
		}
	 	delay_ms(10);
		t++;
		if(t==20)
		{
			t=0;
			LED1=!LED1;
		}
		
		if(temp>30)
		{
			
			delay_ms(100);
		LED0=!LED0;
		delay_ms(100);
		LED1=!LED1;
		GPIO_ResetBits(GPIOA, GPIO_Pin_8);//输出低电平
		delay_ms(100);		
		GPIO_SetBits(GPIOA, GPIO_Pin_8);//输出高电平
		delay_ms(100);			//延时100毫秒
		TIM_SetCompare1(TIM3, 195);//0度
		delay_ms(100);
		TIM_SetCompare1(TIM3, 190);//45度
		delay_ms(100);	
	 sprintf((char*)lora_tx_data,"温度:%d‰\r\n烟雾:%d %$", temp,  ADC_SHIDU);
		lora_transmit(lora_tx_data);	
		delay_ms(100);	
		}
		if(ADC_SHIDU>40)
		{
			
		delay_ms(100);
		LED0=!LED0;
		delay_ms(100);
		LED1=!LED1;
		GPIO_ResetBits(GPIOA, GPIO_Pin_8);//输出低电平
		delay_ms(100);		
		GPIO_SetBits(GPIOA, GPIO_Pin_8);//输出高电平
		delay_ms(100);			//延时100毫秒
		TIM_SetCompare1(TIM3, 195);//0度
		delay_ms(100);
		TIM_SetCompare1(TIM3, 190);//45度
		delay_ms(100);	
	 sprintf((char*)lora_tx_data,"温度:%d‰\r\n烟雾:%d %$", temp,  ADC_SHIDU);
		lora_transmit(lora_tx_data);	
		delay_ms(100);
		}
		
	}
}

2. LORA.C

#include "lora.h"
//#include "usart.h"
#include "usart1.h"
#include "usart3.h"
#include "delay.h"
#include "led.h"

void MD0_Config(void)	
{
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); // 使能PC端口时钟  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;	//选择对应的引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PC端口
  GPIO_ResetBits(GPIOA, GPIO_Pin_11 );	 //拉低
}

void AUX_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //开启按键端口PA的时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //端口配置为下拉输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);	//初始化端口
	GPIO_ResetBits(GPIOA, GPIO_Pin_4 );	 // 关闭所有LED
}

int AUX(void) 
{
		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 1)
			return 1;
		else
			return 0;
}					
void lora_check(void)
{
	int OK_state = 0;
	while(AUX())//检测模块是否在忙
	{
		 UART1TX("Lora正忙1");
		 delay_ms(500);
	}
	MD0(1);
	delay_ms(40);
	UART1TX("LORA检测中......");
	while(!OK_state)//模块检测成功
	{
		UART3TX("AT");
		UART3Test(&OK_state);	
	}
	UART1TX("LORA检测成功");
	UART1TX("   ");
}

void lora_set(void)
{
	/*#####设置地址#########*/
	int OK_state = 0;
	char addr[20] = {0};int t1 = 0,t2 = 0;
	unsigned char i = 0;
	while(AUX())//等待模块空闲
	{
		 UART1TX("Lora正忙2");
	}
	MD0(1);
	delay_ms(40);
	while(!OK_state)//模块检测成功
	{
		UART3TX("AT+ADDR=00,00");
		UART3Test(&OK_state);
		UART1TX("地址设置中......");
	}
	UART1TX("地址为:");
	UART3TX("AT+ADDR?");
	while(1)
	{
			UART3GetByte(&i);
			if(i==':')
			{
				while(1)
				{
					if(UART3GetByte(&i) == 1 && i!='O')
					{
						addr[t1++]=i;
					}
					else if(i=='O')
						break;	 
				}
				while(1)
				{
						UART1SendByte(addr[t2++]);
						if(t1 == t2)
							break;
				}
				break;
			} 
	}
	UART1TX("  ");
	/*#################设置信道和速率###############*/
	OK_state = 0; 
	t1 = 0;
	t2 = 0;
	
	while(!OK_state)//模块检测成功
	{
		UART3TX("AT+WLRATE=23,5");
		UART3Test(&OK_state);
		UART1TX("信道速率设置中......");
	}
	UART1TX("信道,速率为:");
	UART3TX("AT+WLRATE?");
	while(1)
	{
			UART3GetByte(&i);
			if(i==':')
			{
				while(1)
				{
					if(UART3GetByte(&i) == 1 && i!='O')
					{
						addr[t1++]=i;
					}
					else if(i=='O')
						break;	 
				}
				while(1)
				{
						UART1SendByte(addr[t2++]);
						if(t1 == t2)
							break;
				}
				break;
			} 
	}
	UART1TX("  ");	
/*#############发射功率##############*/
	OK_state = 0; 
	t1 = 0;
	t2 = 0;
	
	while(!OK_state)//模块检测成功
	{
		UART3TX("AT+TPOWER=3");
		UART3Test(&OK_state);
		UART1TX("发射功率设置中......");
	}
	UART1TX("发射功率为:");
	UART3TX("AT+TPOWER?");
	while(1)
	{
			UART3GetByte(&i);
			if(i==':')
			{
				while(1)
				{
					if(UART3GetByte(&i) == 1 && i!='O')
					{
						addr[t1++]=i;
					}
					else if(i=='O')
						break;	 
				}
				while(1)
				{
						UART1SendByte(addr[t2++]);
						if(t1 == t2)
							break;
				}
				break;
			} 
	}
	UART1TX("  ");	
/*#################工作模式###################*/
	OK_state = 0; 
	t1 = 0;
	t2 = 0;
	
	while(!OK_state)//模块检测成功
	{
		UART3TX("AT+CWMODE=0");
		UART3Test(&OK_state);
		UART1TX("工作模式设置中......");
	}
	UART1TX("工作模式为:");
	UART3TX("AT+CWMODE?");
	while(1)
	{
			UART3GetByte(&i);
			if(i==':')
			{
				while(1)
				{
					if(UART3GetByte(&i) == 1 && i!='O')
					{
						addr[t1++]=i;
					}
					else if(i=='O')
						break;	 
				}
				while(1)
				{
						UART1SendByte(addr[t2++]);
						if(t1 == t2)
							break;
				}
				break;
			} 
	}
	UART1TX("  ");		
/*#################发送状态#################*/
	OK_state = 0; 
	t1 = 0;
	t2 = 0;
	
	while(!OK_state)//模块检测成功
	{
		UART3TX("AT+TMODE=0");//0:透明传输,1:定向传输
		UART3Test(&OK_state);
		UART1TX("发送状态设置中......");
	}
	UART1TX("发送状态为:");
	UART3TX("AT+TMODE?");
	while(1)
	{
			UART3GetByte(&i);
			if(i==':')
			{
				while(1)
				{
					if(UART3GetByte(&i) == 1 && i!='O')
					{
						addr[t1++]=i;
					}
					else if(i=='O')
						break;	 
				}
				while(1)
				{
						UART1SendByte(addr[t2++]);
						if(t1 == t2)
							break;
				}
				break;
			} 
	}
	UART1TX("  ");	
/*#############睡眠时间#################*/
	OK_state = 0; 
	t1 = 0;
	t2 = 0;
	
	while(!OK_state)//模块检测成功
	{
		UART3TX("AT+WLTIME=0");
		UART3Test(&OK_state);
		UART1TX("睡眠时间设置中......");
	}
	UART1TX("睡眠时间为:");
	UART3TX("AT+WLTIME?");
	while(1)
	{
			UART3GetByte(&i);
			if(i==':')
			{
				while(1)
				{
					if(UART3GetByte(&i) == 1 && i!='O')
					{
						addr[t1++]=i;
					}
					else if(i=='O')
						break;	 
				}
				while(1)
				{
						UART1SendByte(addr[t2++]);
						if(t1 == t2)
							break;
				}
				break;
			} 
	}
	UART1TX("  ");	
/*################波特率,数据校验位####################*/
	OK_state = 0; 
	t1 = 0;
	t2 = 0;
	
	while(!OK_state)//模块检测成功
	{
		UART3TX("AT+UART=3,0");
		UART3Test(&OK_state);
		UART1TX("波特率,数据校验位设置中......");
	}
	UART1TX("波特率,数据校验位为:");
	UART3TX("AT+UART?");
	while(1)
	{
			UART3GetByte(&i);
			if(i==':')
			{
				while(1)
				{
					if(UART3GetByte(&i) == 1 && i!='O')
					{
						addr[t1++]=i;
					}
					else if(i=='O')
						break;	 
				}
				while(1)
				{
						UART1SendByte(addr[t2++]);
						if(t1 == t2)
							break;
				}
				break;
			} 
	}
	UART1TX("  ");	
	MD0(0);
	delay_ms(40);
	while(AUX());
	USART3_Config(9600); //USART3 配置 
	
	
	UART1TX("LORA配置完成######################");
}



void lora_transmit(char* a)
{
		int i = 0;
		UART3SendByte('#');//起始符
		while(a[i] != '$')
		{
				UART3SendByte(a[i]);
				i++;
		}
		UART3SendByte('$');//结束符
		UART3SendByte('\r');
		UART3SendByte('\n');
		
}


void lora_receive(void)
{
	unsigned char i = 0;
	extern unsigned char lora_rx_data[100];
//		extern char lora_rx_data[9];
	int t1 = 0,t2 = 0;
	while(1)
	{
			UART3GetByte(&i);
			if(i=='#')
			{
				while(1)
				{
					if(UART3GetByte(&i) == 1 && i!='$')
					{
						lora_rx_data[t1++]=i;
					}
					else if(i=='$')
						break;	 
				}
				while(1)
				{
						UART1SendByte(lora_rx_data[t2++]);
						if(t1 == t2)
						{
							UART1SendByte('\r');
							UART1SendByte('\n');
							break;
						}
				}
				break;
			}
	}
				
}

void LORA_Init(void)
{
		MD0_Config(); //初始化MD0 
		AUX_Config();
//		LED_Config();
		lora_check();
		lora_set();   //配置LORA


}

3. DHC11.C

#include "dh11.h"
#include "delay.h"
      
//复位DHT11
void DHT11_Rst(void)	   
{                 
	DHT11_IO_OUT(); 	//SET OUTPUT
    DHT11_DQ_OUT=0; 	//拉低DQ
    delay_ms(20);    	//拉低至少18ms
    DHT11_DQ_OUT=1; 	//DQ=1 
	delay_us(50);     	//主机拉高20~40us
}
//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
u8 DHT11_Check(void) 	   
{   
	u8 retry=0;
	DHT11_IO_IN();//SET INPUT	 
    while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=100)return 1;
	else retry=0;
    while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
	{
		retry++;
		delay_us(1);
	};
	if(retry>=100)return 1;	    
	return 0;
}
//从DHT11读取一个位
//返回值:1/0
u8 DHT11_Read_Bit(void) 			 
{
 	u8 retry=0;
	while(DHT11_DQ_IN&&retry<100)//等待变为低电平
	{
		retry++;
		delay_us(1);
	}
	retry=0;
	while(!DHT11_DQ_IN&&retry<100)//等待变高电平
	{
		retry++;
		delay_us(1);
	}
	delay_us(40);//等待40us
	if(DHT11_DQ_IN)return 1;
	else return 0;		   
}
//从DHT11读取一个字节
//返回值:读到的数据
u8 DHT11_Read_Byte(void)    
{        
    u8 i,dat;
    dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit();
    }						    
    return dat;
}
//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
{        
 	u8 buf[5];
	u8 i;
	DHT11_Rst();
	if(DHT11_Check()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=DHT11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=buf[0];
			*temp=buf[2];
		}
	}else return 1;
	return 0;	    
}
//初始化DHT11的IO口 DQ 同时检测DHT11的存在
//返回1:不存在
//返回0:存在    	 
u8 DHT11_Init(void)
{	 
 
	DHT11_Rst();  //复位DHT11
	return DHT11_Check();//等待DHT11的回应
} 

4. PWM.C

#include "pwm.h"
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u16 arr,u16 psc)
{  
	 GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);// 
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);  //使能GPIO外设时钟使能
	                                                                     	

   //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //TIM_CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	
	TIM_TimeBaseStructure.TIM_Period = 199; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 80K
	TIM_TimeBaseStructure.TIM_Prescaler =7199; //设置用来作为TIMx时钟频率除数的预分频值  
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

  TIM_CtrlPWMOutputs(TIM3,ENABLE);	//MOE 主输出使能	

	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //CH1预装载使能	 
	
	TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器
	
	TIM_Cmd(TIM3, ENABLE);  //使能TIM1
 
   
}

5.ADC.C

#include "adc.h"
void Adc_Init(void)
{

    ADC_InitTypeDef ADC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);

    RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12MHZ 
    
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
    
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);
    

  ADC_Cmd(ADC1, ENABLE);

 
  ADC_ResetCalibration(ADC1);
 
  while(ADC_GetResetCalibrationStatus(ADC1));

 
  ADC_StartCalibration(ADC1);
 
  while(ADC_GetCalibrationStatus(ADC1));
}

u16 Get_val(u8 ch)
{
    u16 DataValue; 

  ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);
    
  
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    

    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
    
 DataValue = ADC_GetConversionValue(ADC1); 
return DataValue; 
} 

u16 ADC_Get_aveg(u8 ch,u8 n) 
{ 
	u32 ad_sum = 0; 
	u8 i; 
	for(i=0;i<n;i++) 
	{ 
	ad_sum += Get_val(ch);
	 delay_ms(5); 
	} 
	return (ad_sum / n);
 }

  • 2
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
基于Lora技术的水表集中采集系统一种利用无线通信技术实现远程水表数据采集的系统。该系统包括水表、Lora通信模块、数据采集终端和数据接收服务器等组成部分。 首先,每个水表都装备了Lora通信模块,通过无线方式将水表读数和其他相关数据传输给数据采集终端。Lora通信技术具有广阔的覆盖范围和较低的功耗,能够实现长距离、低功耗的数据传输,方便实现水表远程读数。 其次,数据采集终端负责收集水表传输的数据,并进行处理和存储。该终端具备数据处理和存储功能,能够自动收集水表的读数数据,并将其存储到本地数据库中。同时,数据采集终端还具备与数据接收服务器的通信能力,能够将采集到的数据传送给服务器进行进一步处理和管理。 最后,数据接收服务器是整个系统的核心部分,负责接收和管理从数据采集终端传来的水表数据。服务器能够对接收到的数据进行分析和处理,并可根据需求生成水表用水量报表、异常报警等功能,帮助用水单位或管理部门进行用水管理和监控。 基于Lora技术的水表集中采集系统具有多个优势。首先,它能实现水表的远程自动读数,省去了人工收集水表读数的时间和人力成本。其次,系统具备低功耗和长距离的通信特性,能够实现水表数据的远程传输,避免了传统有线采集方式的限制。最后,系统能够通过数据处理和分析,帮助用水单位进行用水量管控和异常监测,提高用水管理的效率和精度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值