STM32(F103ZET6)第十六课:WIFI模块的配置与应用

news2024/9/24 23:23:13

目录

  • 需求
    • 一、wifi模块简述
    • 二、配置流程
      • 1.配置通信串口
      • 2.配置引脚与中断接受
      • 3.简述AT指令
      • 4.程序编写
    • 三、需求实现代码

需求

完成WiFi模块的配置,使其能连接服务器并最终能和服务器相互发送消息。
在这里插入图片描述

一、wifi模块简述

本项目开发版上没有封装好的WIFI模块,所以借助外部wifi模块。
ESP8266:乐鑫公司推出的一款无线SOC。可以直接使用ESP_IDF、Arduino直接编程
ESP_12F:安信可公司在ESP8266芯片的基础上,封装出的一个模块
在这里插入图片描述
模块原理图:
在这里插入图片描述
模块引脚配置:
在这里插入图片描述
通信接口配置:
在这里插入图片描述

二、配置流程

1.配置通信串口

配置串口3(本次使用的WiFi模块串口接的是串口3)
默认配置: 波特率115200  8位数据位 0位校验位 1位停止位
配置PB10(TX) PB11(RX)
TX:复用推挽 RX:浮空输入
配置PE6(ESP模块的使能引脚)
高电平使能
代码编写:

/*****************************************************************
 *函 数 名 称:USART3_Config
 *函 数 功 能:初始化串口3
 *函 数 形 参:无
 *函 数 返 回:无
*******************************************************************/
void USART3_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct={0};
	USART_InitTypeDef USART_InitStruct={0};
	NVIC_InitTypeDef NVIC_InitStruct={0};
	//1,开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
	//2,配置IO口
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	//3,配置串口
	USART_InitStruct.USART_BaudRate=115200;
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_InitStruct.USART_Parity=USART_Parity_No;  
	USART_InitStruct.USART_StopBits=USART_StopBits_1;
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;

	USART_Init(USART3,&USART_InitStruct);
	//4,使能串口
	USART_Cmd(USART3,ENABLE);
	//5,开中断
	USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
	USART_ITConfig(USART3,USART_IT_IDLE,ENABLE);
	//6,配置中断
	NVIC_InitStruct.NVIC_IRQChannel=USART3_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;//响应优先级
	NVIC_Init(&NVIC_InitStruct);
}
/*****************************************************************
 *函 数 名 称:WIFI_Config
 *函 数 功 能:初始化WIFI
 *函 数 形 参:无
 *函 数 返 回:无
*******************************************************************/
void WIFI_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct={0};
	//配置通信串口
	USART3_Config();
	//配置使能引脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
	//2,配置IO口
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	
	GPIO_SetBits(GPIOE,GPIO_Pin_6);
	Delay_nms(500);//延时让WIFI输出固件信息
}

2.配置引脚与中断接受

在中断中进行信息的接受

/*****************************************************************
 *函 数 名 称:USART3_IRQHandler
 *函 数 功 能:初始化串口3
 *函 数 形 参:无
 *函 数 返 回:无
*******************************************************************/
void USART3_IRQHandler(void)
{
	uint8_t data=0;
	if(USART_GetITStatus(USART3,USART_IT_RXNE) == SET)
	{
		data = USART3->DR;
		rxdata.rxbuff[rxdata.rxcnt++] = data;
		rxdata.rxcnt %= MAX;//确保不越界
		USART1->DR = data;//通过串口1将数据发给电脑串口助手
	}
	if(USART_GetITStatus(USART3,USART_IT_IDLE) == SET)
	{
		rxdata.rxflag = 1;
		data = USART3->SR;
		data = USART3->DR;
	}	
}

3.简述AT指令

AT 命令(AT Commands)最早是由发明拨号调制解调器(MODEM)的贺氏公司(Hayes)为了控制 MODEM 而发明的控制协议。后来随着网络带宽的升级,速度很低的拨号 MODEM 基本退出一般使用市场,但是 AT 命令保留下来。
  在嵌入式开发中,经常是使用AT命令去控制各种通讯模块,比如ESP8266 WIFI模块、4G模块、GPRS模块等等。一般就是主芯片通过硬件接口(比如串口、SPI)发送AT命令给通讯模块,模块接收到数据之后回应响应的数据。
AT指令的分类:
在这里插入图片描述
在这里插入图片描述
AT指令的使用:
要注意:基本所有AT指令,结尾必须换行(\r\n),除“+++”以外
ESP12F模块的工作模式:STA(连接热点) AP(释放热点) STA+AP
STA模式:模组作为节点去连接热点,然后就可连接某个服务器。
AP模式:模组作为热点,释放网络,可以在模组上创建服务器,其他设备连接他。
该模块的指令:
AT :测试固件的
AT+RST :重启ESP8266
ATE0 :关闭回显
ATE1 :打开回显
AT+CWMODE_DEF(_DEF有些固件支持,有些不支持)=x
x=1为设置工作模式 STA模式(可以连接其他设备热点),2为AP模式,3为组合模式。
AT+CWJAP_DEF=“WIFI名”,“WIFI密码” 连接WIFI。
AT+CWSAP :配置 ESP8266 SoftAP 参数(配置释放的热点) 。
AT+CIPAP :设置 ESP8266 SoftAP 的 IP 地址。
多连接情况下 (AT+CIPMUX=1),才能开启 TCP 服务器。
AT+CIPSERVER :建⽴ TCP 服务器
AT+CIPSTART=“TCP”,“IP”,端口号 以TCP的形式连接服务器
AT+CIPMODE=1 : 开启透传 (向wifi发送的所有消息(除+++外)都认为不是指令)
AT+CIPSEND : 启动发送功能

+++ 没有回车 : 退出透传
AT+CIPCLOSE : 退出服务器连接
以上的指令都是比较常用的,所以应当熟记。
连接服务器需要那些步骤:
1.连接网络
2.设置位连接热点模式:STA
3.连接热点:名字和密码
4.连接服务器 ip 和 端口
5.收发数据
AT是AT指令还是收发的数据
透传模式(透明传输,所有消息都认为是普通收发的消息)

4.程序编写

给串口发送AT指令,相当于发送字符串。
本项目相当于WIFI模块经过串口三发给串口一,经过串口一发送给串口助手。
在这里插入图片描述
发送单个字符的代码:

/*****************************************************************
 *函 数 名 称:USART3_SendData
 *函 数 功 能:串口3发送单个字节
 *函 数 形 参:data :发送的内容
 *函 数 返 回:无
*******************************************************************/
void USART3_SendData(uint8_t data)
{
	while(USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET);
	USART3->DR = data;
	while(USART_GetFlagStatus(USART3,USART_FLAG_TC) == RESET);
}

发送字符串:

/*****************************************************************
 *函 数 名 称:USART3_SendStr
 *函 数 功 能:串口3发送字符串
 *函 数 形 参:Str:发送的内容	 len:长度
 *函 数 返 回:无
*******************************************************************/
void USART3_SendStrLen(uint8_t *Str,uint16_t len)
{
	uint16_t i=0;
	for(i=0;i<len;i++)
	{
		USART3_SendData(Str[i]);
	}
}

定义一个WIFI的结构体进行信息的收发。
在这里插入图片描述
再写一个指令发送的函数.

/*****************************************************************
 *函 数 名 称:WIFI_SendCmd
 *函 数 功 能:发送指令,并且判断是否发送成功
 *函 数 形 参:CMD:发送的指令内容
							 ACK:期待回复的数据
							 TIME:等待时间 单位ms
 ***函 数 返 回:成功返回0 失败返回1**
*******************************************************************/
uint8_t WIFI_SendCmd(uint8_t* CMD,uint8_t* ACK,uint16_t TIME)
{
	memset(&rxdata,0,sizeof(rxdata));//清数据
	USART3_SendStr(CMD);
	while(TIME--)//超时检测机制
	{
		if(rxdata.rxflag == 1) //接受完成之后再查找
		{
			rxdata.rxflag = 0;
			if(strstr((char *)rxdata.rxbuff,(char *)ACK) != NULL)
			{
				memset(&rxdata,0,sizeof(rxdata));//清数据
				return 0;//查到正确返回值
			}
		}
		Delay_nms(1);
	}
	memset(&rxdata,0,sizeof(rxdata));//清数据
	return 1;//规定时间没查到
}

其中strstr函数为查询目标字符串种是否有所需字符串,若有则返回所需字符串的地址,没有则返回0。
strstr(目标字符串,所需字符串)

链接服务器的函数:

/*****************************************************************
 *函 数 名 称:WIFI_ConnectSever
 *函 数 功 能:WIFI链接服务器
 *函 数 形 参:无
 *函 数 返 回:成功返回0 失败返回1
*******************************************************************/
uint8_t WIFI_ConnectSever(char *severIP,uint16_t Port)
{
	char buff[100]={0};
	if(WIFI_SendCmd((u8*)"AT\r\n",(u8*)"OK",100) == 0)
	{
		printf("WIFI 正常工作\r\n");
		if(WIFI_SendCmd((u8*)"AT+CWMODE=1\r\n",(u8*)"OK",100) == 0)
		{
			printf("WIFI 模式设置完成\r\n");
			if(WIFI_SendCmd((u8*)"AT+CWJAP=\"cmyddf\",\"88888888\"\r\n",(u8*)"OK",30000) == 0)
			{
				printf("WIFI 热点链接完成\r\n");
				sprintf(buff,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",severIP,Port);
				if(WIFI_SendCmd((u8*)buff,(u8*)"OK",3000) == 0)
				{
					printf("WIFI 服务器链接完成\r\n");
					WIFI_SendCmd((u8*)"AT+CIPMODE=1\r\n",(u8*)"OK",3000);
					WIFI_SendCmd((u8*)"AT+CIPSEND\r\n",(u8*)"OK",3000);
					printf("请发送数据\r\n");
					return 0;
				}
				return 1;
			}
			return 1;
		}
		return 1;
	}
	return 1;
}

三、需求实现代码

main.c

//WIFI任务
TaskHandle_t Ali_TaskHandle;
void Ali_Task(void *p)
{
		uint16_t cnt=0;
	  MyPrintf("Ali_Task begin\r\n"); //传感器开始
		WIFI_ConnectSever(Sever_IP, SeverPort);//链接wifi
		MQTT_Connect(ClientID, UserName,PassWord,3000);//发布报文
		Delay_nms(1000);
		MQTT_Subscribe(Subscribe_Topic);//订阅时钟同步主题
		Delay_nms(1000);	
		MQTT_Publish(Publish_NTPTopic,(u8*)"{\"deviceSendTime\":\"123\"}");
	while(1)
	{	cnt++;
		WIFI_Anylze();
		vTaskDelay(10);
		if(cnt>=500)
		{
			cnt=0;
			MQTT_Publish(Publish_Topic,(u8 *)Payload);
		}		
	}
}

wifi.c

#include "wifi.h"
#include "delay.h"
#include "string.h"
#include "stdio.h"
#include "led.h"
#include "stdlib.h"
#include "rtc.h"

WIFI_DATA rxdata={0};

//串口3 PB10 - TX  PB11 - RX
/*****************************************************************
 *函 数 名 称:USART3_Config
 *函 数 功 能:初始化串口3
 *函 数 形 参:无
 *函 数 返 回:无
 *作       者:CYM
 *修 改 日 期:xx/xx/xx
*******************************************************************/
void USART3_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct={0};
	USART_InitTypeDef USART_InitStruct={0};
	NVIC_InitTypeDef NVIC_InitStruct={0};
	//1,开时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
	//2,配置IO口
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	//3,配置串口
	USART_InitStruct.USART_BaudRate=115200;
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_InitStruct.USART_Parity=USART_Parity_No;  
	USART_InitStruct.USART_StopBits=USART_StopBits_1;
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;

	USART_Init(USART3,&USART_InitStruct);
	//4,使能串口
	USART_Cmd(USART3,ENABLE);
	//5,开中断
	USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
	USART_ITConfig(USART3,USART_IT_IDLE,ENABLE);
	//6,配置中断
	NVIC_InitStruct.NVIC_IRQChannel=USART3_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;//响应优先级
	NVIC_Init(&NVIC_InitStruct);
}

/*****************************************************************
 *函 数 名 称:WIFI_Config
 *函 数 功 能:初始化WIFI
 *函 数 形 参:无
 *函 数 返 回:无
 *作       者:CYM
 *修 改 日 期:xx/xx/xx
*******************************************************************/
void WIFI_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct={0};
	//配置通信串口
	USART3_Config();
	//配置使能引脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
	//2,配置IO口
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	
	GPIO_SetBits(GPIOE,GPIO_Pin_6);
	Delay_nms(500);//延时让WIFI输出固件信息
}

/*****************************************************************
 *函 数 名 称:USART3_IRQHandler
 *函 数 功 能:初始化串口4
 *函 数 形 参:无
 *函 数 返 回:无
 *作       者:CYM
 *修 改 日 期:xx/xx/xx 01 02 03 
*******************************************************************/
void USART3_IRQHandler(void)
{
	uint8_t data=0;
	if(USART_GetITStatus(USART3,USART_IT_RXNE) == SET)
	{
		data = USART3->DR;
		rxdata.rxbuff[rxdata.rxcnt++] = data;
		rxdata.rxcnt %= MAX;//确保不越界
		USART1->DR = data;//通过串口1将数据发给电脑串口助手
	}
	if(USART_GetITStatus(USART3,USART_IT_IDLE) == SET)
	{
		rxdata.rxflag = 1;
		data = USART3->SR;
		data = USART3->DR;
	}	
}

/*****************************************************************
 *函 数 名 称:USART3_SendData
 *函 数 功 能:串口3发送单个字节
 *函 数 形 参:data :发送的内容
 *函 数 返 回:无
 *作       者:CYM
 *修 改 日 期:xx/xx/xx
*******************************************************************/
void USART3_SendData(uint8_t data)
{
	while(USART_GetFlagStatus(USART3,USART_FLAG_TXE) == RESET);
	USART3->DR = data;
	while(USART_GetFlagStatus(USART3,USART_FLAG_TC) == RESET);
}

/*****************************************************************
 *函 数 名 称:USART3_SendStr
 *函 数 功 能:串口3发送字符串
 *函 数 形 参:Str:发送的内容
							 len:长度
 *函 数 返 回:无
 *作       者:CYM
 *修 改 日 期:xx/xx/xx
*******************************************************************/
void USART3_SendStrLen(uint8_t *Str,uint16_t len)
{
	uint16_t i=0;
	for(i=0;i<len;i++)
	{
		USART3_SendData(Str[i]);
	}
}

void USART3_SendStr(uint8_t *Str)
{
	while(*Str != '\0')
	{
		USART3_SendData(*Str);
		Str++;
	}
}

/*****************************************************************
 *函 数 名 称:WIFI_SendCmd
 *函 数 功 能:发送指令,并且判断是否发送成功
 *函 数 形 参:CMD:发送的指令内容
							 ACK:期待回复的数据
							 TIME:等待时间 单位ms
 *函 数 返 回:成功返回0 失败返回1
 *作       者:CYM
 *修 改 日 期:xx/xx/xx
*******************************************************************/
uint8_t WIFI_SendCmd(uint8_t* CMD,uint8_t* ACK,uint16_t TIME)
{
	memset(&rxdata,0,sizeof(rxdata));//清数据
	USART3_SendStr(CMD);
	while(TIME--)//超时检测机制
	{
		if(rxdata.rxflag == 1) //接受完成之后再查找
		{
			rxdata.rxflag = 0;
			if(strstr((char *)rxdata.rxbuff,(char *)ACK) != NULL)
			{
				memset(&rxdata,0,sizeof(rxdata));//清数据
				return 0;//查到正确返回值
			}
		}
		Delay_nms(1);
	}
	memset(&rxdata,0,sizeof(rxdata));//清数据
	return 1;//规定时间没查到
}

/*****************************************************************
 *函 数 名 称:WIFI_ConnectSever
 *函 数 功 能:WIFI链接服务器
 *函 数 形 参:无
 *函 数 返 回:成功返回0 失败返回1
 *作       者:CYM
 *修 改 日 期:xx/xx/xx
*******************************************************************/
uint8_t WIFI_ConnectSever(char *severIP,uint16_t Port)
{
	char buff[100]={0};
	if(WIFI_SendCmd((u8*)"AT\r\n",(u8*)"OK",100) == 0)
	{
		printf("WIFI 正常工作\r\n");
		if(WIFI_SendCmd((u8*)"AT+CWMODE=1\r\n",(u8*)"OK",100) == 0)
		{
			printf("WIFI 模式设置完成\r\n");
			if(WIFI_SendCmd((u8*)"AT+CWJAP=\"cmyddf\",\"88888888\"\r\n",(u8*)"OK",30000) == 0)
			{
				printf("WIFI 热点链接完成\r\n");
				sprintf(buff,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",severIP,Port);
				if(WIFI_SendCmd((u8*)buff,(u8*)"OK",3000) == 0)
				{
					printf("WIFI 服务器链接完成\r\n");
					WIFI_SendCmd((u8*)"AT+CIPMODE=1\r\n",(u8*)"OK",3000);
					WIFI_SendCmd((u8*)"AT+CIPSEND\r\n",(u8*)"OK",3000);
					printf("请发送数据\r\n");
					return 0;
				}
				return 1;
			}
			return 1;
		}
		return 1;
	}
	return 1;
}


/*****************************************************************
 *函 数 名 称:WIFI_Anylze
 *函 数 功 能:WIFI接受解析
 *函 数 形 参:无
 *函 数 返 回:无
 *作       者:CYM
 *修 改 日 期:xx/xx/xx
*******************************************************************/
void WIFI_Anylze(void)
{
	uint32_t GetTime=0;
	uint32_t nowtime=0;
	char *p=NULL;
	char buff[12]={0};
	uint8_t i = 0;
	if(rxdata.rxflag == 1)
	{
		if(rxdata.rxbuff[0] == '1')
			Led_ON(1);
		if(rxdata.rxbuff[0] == '0')
			Led_OFF(1);
		if(strstr((const char *)rxdata.rxbuff+10,"serverSendTime") != NULL )
		{
			printf("收到时间同步消息\r\n");
			p = strstr((const char *)rxdata.rxbuff+10,"serverSendTime");
			p += 17;
			for(i=0;i<10;i++)
			{
				buff[i] = p[i];
			}
			GetTime=atoi(buff);
			printf("提取出的时间结果:%d\r\n",GetTime);
			//将获取到的时间,写入到RTC的计数器里即可。
			//RTC_Configuration(GetTime);
			nowtime=GetTime+8*60*60;
			RTC_Configuration(nowtime);
		}
		if(strstr((const char *)rxdata.rxbuff+10,"\"powerstate\":1") != NULL )
		{
			Led_ON(1);
		}
		if(strstr((const char *)rxdata.rxbuff+10,"\"powerstate\":0") != NULL )
		{
			Led_OFF(1);
		}
		memset(&rxdata,0,sizeof(rxdata));
	}	
}


wifi.h

#ifndef __WIFI_H
#define __WIFI_H

#include "stm32f10x.h"

#define MAX 1024

typedef struct{
	uint8_t rxbuff[MAX];//保存接受数据
	uint16_t rxcnt;//记录接受数据个数
	uint8_t rxflag;//接受完成标志
}WIFI_DATA;
extern WIFI_DATA rxdata;

uint8_t WIFI_ConnectSever(char *severIP,uint16_t Port);
void USART3_SendStrLen(uint8_t * Str,uint16_t len);
void WIFI_Config(void);
void WIFI_Anylze(void);

#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2077981.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot日常:基于DeferredResult的异步处理

文章目录 示例代码代码执行结果代码执行过程解析DeferredResult 的优势 本章内容主要讲讲基于DeferredResult的异步处理 在 Servlet 容器中启用了异步请求处理功能&#xff0c;控制器方法就可以用 包装任何支持的控制器方法返回值DeferredResult&#xff0c;控制器可以从不同的…

谷粒商城实战笔记-261~262-商城业务-订单服务-页面环境搭建-SpringSession

文章目录 一&#xff0c;261-商城业务-订单服务-页面环境搭建1&#xff0c;静态资源上传2&#xff0c;配置域名映射3&#xff0c;网关配置4&#xff0c;页面静态资源引用修改 二&#xff0c;262-商城业务-订单服务-整合SpringSession1&#xff0c;页面跳转2&#xff0c;配置Spr…

Python实战:如何使用K-means算法进行餐馆满意度NLP情感分析

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

详解Apache 和 Tomcat 整合原理及区别

Apache 和 Tomcat 都是Web服务器&#xff0c;它们之间既有联系又有区别。Apache主要负责静态解析&#xff0c;如HTML。Tomcat主要负责动态解析&#xff0c;如JSP。 为什么要让 Apache 与 Tomcat 之间进行连接呢? 原因有下面几个&#xff1a; 提升对静态文件的处理性能 利用…

ms_送给新人的面试题简单解答

第一部分 1 项目中遇到的bug或者难题 这个问题比较容易&#xff0c;每个人都会在开发过程中遇到或多或少的问题&#xff0c;你不可能答我已经天下无敌了&#xff0c;大家开发的项目类型都不太一样&#xff0c;事实上也没人听得太仔细&#xff0c;就算你要说的‘难题‘并不难&…

Apache Druid日志实时分析

业务分析 ​ 秒杀业务中&#xff0c;通常会有很多用户同时蜂拥而上去抢购热卖商品&#xff0c;经常会出现抢购人数远大于商品库存。其实在秒杀过程中&#xff0c;热卖商品并不多&#xff0c;几乎只占1%&#xff0c;而99%的流量都源自热卖商品&#xff0c;很有可能因为这1%的热…

【SQL】分类统计的薪水

目录 题目 分析 代码 题目 表: Accounts ------------------- | 列名 | 类型 | ------------------- | account_id | int | | income | int | ------------------- 在 SQL 中&#xff0c;account_id 是这个表的主键。 每一行都包含一个银行帐户的月收入的…

深入解析Go语言os/user包:用户和组管理实战指南

深入解析Go语言os/user包&#xff1a;用户和组管理实战指南 引言什么是os/user包&#xff1f;为什么要学习os/user包&#xff1f;本文将介绍的内容 os/user包基础如何导入os/user包获取当前用户信息示例代码 *user.User类型详解常见错误处理小结 用户查询与管理根据用户名查询用…

这本大模型书籍我敢说知道的人不超过1%,大模型入门必备书籍

当然可以&#xff01;我为您推荐一本关于大模型的书籍&#xff1a;《Transformer Tutorials: From Theory to Practice》。虽然这本书不是直接以“大模型”命名&#xff0c;但它涵盖了构建和理解大规模语言模型&#xff08;如GPT系列和BERT&#xff09;所需的关键技术和理论。接…

娱乐社交、游戏行业的最新玩法实践与未来增长趋势解读|网易数智x华为云城市沙龙杭州站邀你前来!

随着5G、AI、区块链等前沿技术的深度融合应用&#xff0c;泛娱乐行业正经历深刻变革的同时&#xff0c;也面临着一系列挑战与问题&#xff0c;面对社交产品监管的加强、海外市场的双重机遇与风险以及增速放缓的游戏行业...... 探求新增长点与新思路成为当下泛娱乐行业从业者的关…

收银系统源码助力零售门店数字化升级

一、国内零售业数字化转型迈入深水区 近年来&#xff0c;我国零售业数字化进程显著加速&#xff0c;从线上电商到新零售模式&#xff0c;再到利用大数据、人工智能等技术优化供应链、提升体验&#xff0c;每一步都见证了行业的深刻变革。随着零售行业进入存量市场竞争&#xf…

nuxt3连接mongodb操作

文章目录 创建一个nuxt3应用添加nuxt后端服务nuxt3路由创建mongo数据连接mongodb数据库补充添加显示(用v-for打印出数组)nuxt-server-insertmongodb删除数据创建一个nuxt3应用 Node.js - v18.0.0 或更新版本推荐使用 Visual Studio Code 以及 Volar 扩展npx nuxi@latest init p…

使用jwt实现登录验证

jwt工具类 public class JwtUtil {public static String key"mykey";public static String genToken(String username) {JWTCreator.Builder builder JWT.create();Map<String, Object> headersnew HashMap<>();headers.put("typ","jwt&…

uniapp重新编译在微信开发者工具跳转指定页面

uniapp重新编译在微信开发者工具跳转指定页面 步骤 选择编译模式添加编译模式设置启动页面

rk3588调用NPU、查看npu的使用情况

1、rk3588启用NPU 启用三个内核->RKNNLite.NPU_CORE_0_1_2 rknn_lite RKNNLite(verboseFalse) ret rknn_lite.load_rknn(RKNN_MODEL) ret rknn_lite.init_runtime(core_maskRKNNLite.NPU_CORE_0_1_2) 2、查看NPU使用情况&#xff1a; watch sudo cat /sys/kernel/deb…

LaViT:Less-Attention Vision Transformer的特性与优点

引言 https://arxiv.org/pdf/2406.00427 随着计算机视觉领域的发展&#xff0c;视觉Transformer&#xff08;ViTs&#xff09;逐渐成为一项重要技术。尽管ViTs在捕捉图像中的长距离依赖关系方面表现出色&#xff0c;但其沉重的计算负担和潜在的注意力饱和问题一直是实际应用的…

利用Python对Excel数据进行条件筛选与排序

目录 一、Python与Excel数据处理的基础知识 1.1 Python中的Excel数据处理库 1.2 pandas库简介 二、使用pandas读取Excel数据 三、Excel数据的条件筛选 3.1 单条件筛选 3.2 多条件筛选 3.3 使用query方法 四、Excel数据的排序 4.1 单列排序 4.2 多列排序 五、案例分…

Python自动化:Excel根据IP匹配网段获取所属源端口

需求 现在有两个文件&#xff1a; 1. 【NTP.xlsx】&#xff1a;有name、IP、fenzhihang、vendor、source这五列 2. 【IP.xlsx】&#xff1a;有daqu、fenzhihang、duankou、IP、mask、gateway、subnet、yongtu、miaoshu这九列 现在更新基线&#xff0c;每台设备都需要增加nt…

ET6框架(二)Demo工程的运行及编译

1.工程下载地下&#xff1a; GitHub - egametang/ET at release6.0 2.复制地址后下载&#xff0c;在本人使用时ET已更新到最新9.0的版本&#xff0c;因此下载后需要切换分支到6.0版本 3.下载完工程后可以用 UnityHub打开工程&#xff0c;如没有对应版本可以在&#xff1a;h…

OpenHarmony技术开发:Launcher架构应用启动流程分析

简介 Launcher 作为系统人机交互的首要入口&#xff0c;提供应用图标的显示、点击启动、卸载应用&#xff0c;并提供桌面布局设置以及最近任务管理等功能。 Launcher 采用 扩展的 TS 语言&#xff08;eTS&#xff09;开发&#xff0c;主要的结构如下&#xff1a; product 业务…