单片机-STM32 WIFI模块--ESP8266 (十二)

news2025/1/29 13:56:02

1.WIFI模块--ESP8266

名字由来:

Wi-Fi这个术语被人们普遍误以为是指无线保真(Wireless Fidelity),并且即便是Wi-Fi联盟本身也经常在新闻稿和文件中使用“Wireless Fidelity”这个词,Wi-Fi还出现在ITAA的一个论文中。但事实上,Wi-Fi一词没有任何意义,也是没有全写的。

原理部分

无线网络在无线局域网的范畴是指“无线相容性认证”,实质上是一种商业认证,同时也是一种无线联网技术,以前通过网线连接电脑,而Wi-Fi则是通过无线电波来连网;常见的就是一个无线路由器,那么在这个无线路由器的电波覆盖的有效范围都可以采用Wi-Fi连接方式进行联网,如果无线路由器连接了一条ADSL线路或者别的上网线路,则又被称为热点。

ESP8266外观图:

ESP8266如何通信:

需要使用单片机的串口控制ESP8266

因为ESP8266目前预留的就是。

单片机---》ESP8266

ESP8266的特性:

不同的WIFI模块对比:

了解以下公司:

乐鑫信息科技

安信可

有人科技

移远科技

TCP和UDP的区别

TCP是一种面向连接,可靠的稳定的网络通信方式,连接的时候必须有应答,可以确定数据传输的顺序

UDP连接是一种面向无连接的通信,发送方发送数据,不需要给回复,发送方只负责发送数据,但是数据是否发送完成,不去负责。

2.AT指令集

AT指令集是从终端设备(Terminal Equipment,TE)或数据终端设备(Data Terminal Equipment,DTE)向终端适配器(Terminal Adapter, TA)或数据电路终端设备(Data Circuit Terminal Equipment,DCE)发送的。

AT指令集是现在已经设置好的一套指令,用于驱动外部设备,如果需要使用AT指令集控制外部设备的话,需要首先熟悉AT操作。

单片机和ESP8266连接图:

为什么使用AT指令集??

1.ESP8266内部已经集成了TCP/IP协议,而且也烧写了相关固件

2.我们的MCU部分只需要像控制OLED屏一样发送指令即可

3.ESP8266控制指令全部用的都是AT指令集

ESP8266相关的AT指令集

AT指令集的四种类型:

比如,我们要查询串口配置:

        AT_UART?

设置串口:

AT+UART=<baudrate>,<databits>,<stopbits>,<pa rity>,<flow control>

AT--测试指令

ATE--回显设置

AT+RST--复位

AT+GMR--查询版本信息

AT+CWMODE—设置 Wi-Fi 模式

Station--客户端

SoftAP--服务器

SoftAP+Station--混合模式

AT+CWJAP—连接 AP

AT+CPIMUX--设置连接

AT+CIPMODE—设置传输模式

AT+CIPSTART—建⽴立 TCP 连接, UDP 传输或 SSL 连接

ESP8266透传

AT
ATE0  关闭回显
AT+CWMODE= 1  //客户端
AT+CWJAP="WLL001","123456789"    //
AT+CIPMUX=0  //0--单链接

AT+CIPSTART1
="TCP","120.76.100.197",10002  //设置服务器IP端口
AT+CIPMODE=1  //透传模式

AT+CIPSEND     
>            //收发数据
注意每一个指令的结尾都需要换行符

[15:24:06.186]发→◇AT


OK

[15:24:27.367]发→◇AT+CWMODE=1
□
[15:24:27.372]收←◆AT+CWMODE=1

OK

[15:27:47.266]发→◇AT
□
[15:27:47.271]收←◆AT

OK

[15:27:51.816]发→◇AT+CWMODE=1
□
[15:27:51.820]收←◆AT+CWMODE=1

OK

[15:27:55.146]发→◇AT+CWJAP="WLL001","123456789"
□
[15:27:55.153]收←◆AT+CWJAP="WLL001","123456789"

[15:28:09.220]收←◆+CWJAP:3

FAIL

[15:28:43.918]发→◇AT+CWJAP="WLL001","123456789"
□
[15:28:43.925]收←◆AT+CWJAP="WLL001","123456789"

[15:28:47.907]收←◆WIFI CONNECTED

[15:28:48.731]收←◆
OK
WIFI GOT IP

[15:28:53.611]发→◇AT+CIPMUX=0
□
[15:28:53.616]收←◆AT+CIPMUX=0

OK



[15:29:16.708]发→◇AT+CIPSTART="TCP","192.168.137.1",8080
□
[15:29:16.714]收←◆AT+CIPSTART="TCP","192.168.137.1",8080
CONNECT

OK

[15:29:42.209]发→◇AT+CIPMODE=1
□
[15:29:42.219]收←◆AT+CIPMODE=1

OK

[15:30:15.994]发→◇AT+CIPSEND
>
□
[15:30:15.999]收←◆AT+CIPSEND
>

busy p...

OK

>
[15:30:27.237]发→◇hello
□
[15:30:31.699]收←◆http://www.cmsoft.cn
[15:30:47.653]发→◇+++
□
[15:31:23.607]发→◇+++□
[15:31:28.834]发→◇+++□
[15:31:28.837]收←◆+++
[15:31:55.340]发→◇AT+CIPMODE=0

□
[15:31:55.346]收←◆AT+CIPMODE=0

busy p..
ERROR

[15:33:24.341]发→◇AT+CIPSTART="TCP","192.168.137.1",8080
□
[15:33:24.349]收←◆AT+CIPSTART="TCP","192.168.137.1",8080
ALREADY CONNECTED

ERROR

[15:33:24.560]发→◇AT+CIPSTART="TCP","192.168.137.1",8080
□
[15:33:24.566]收←◆AT+CIPSTART="TCP","192.168.137.1",8080
ALREADY CONNECTED

3.单片机串口配置

1.选择一个串口(串口2 或者串口3 串口4.。。。。都可以)

2.串口的接收中断,用于接收数据

3.判断数据是否接收完成的方式:

        a.串口的空闲中断,用于判断数据是否接收完成,(因为接受的数据是不定长)

        b.使用定时器进行判断,比如当开始接收数据的时候,打开定时器,当定时器计数3秒还没有数据再次到来,就可以判断数据接收。

4.接收到数据之后,解析数据

查找接收到的字符串中的关键字,比如“Ok”

5.复位管教和使能管教的的配置

随便找两个管教设置为,通用推完输出即可

使能(EN)---驱动ESP8266

RST--拉高--PG14

EN--拉高--PG13

使用的是串口3

TX--PB10

RX--PB11

串口3的配置部分:

void esp8266_Init(void)
{
    GPIO_InitTypeDef GPIOInitTypeDef;
    USART_InitTypeDef USARTInitTypeDef;
    //打开时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
    //配置PB10--TX PB11--RX
    //PB10--复用推挽输出
    GPIOInitTypeDef.GPIO_Pin=GPIO_Pin_10;
    GPIOInitTypeDef.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIOInitTypeDef.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIOInitTypeDef);
    //PB11--浮空
    GPIOInitTypeDef.GPIO_Pin=GPIO_Pin_11;
    GPIOInitTypeDef.GPIO_Mode=GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB,&GPIOInitTypeDef);
    //usart3的配置
    USARTInitTypeDef.USART_BaudRate=115200;
    USARTInitTypeDef.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
    USARTInitTypeDef.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
    USARTInitTypeDef.USART_Parity=USART_Parity_No;
    USARTInitTypeDef.USART_StopBits=USART_StopBits_1;
    USARTInitTypeDef.USART_WordLength=USART_WordLength_8b;
    USART_Init(USART3,&USARTInitTypeDef);
    //配置中断
    //设置空闲中断和接收中断
    USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
    USART_ITConfig(USART3,USART_IT_IDLE,ENABLE);
    
    //

    NVIC_SetPriority(USART3_IRQn,0);//占先优先级:1 次级优先级:1 
    NVIC_EnableIRQ(USART3_IRQn);
    USART_Cmd(USART3,ENABLE);
    
    



}

ESP8266的使能管脚和复位管脚的配置:

void ESP8266_IO_Config(void)
{
    GPIO_InitTypeDef gpio_initsources;
    //打开时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);
    gpio_initsources.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14;
    gpio_initsources.GPIO_Mode=GPIO_Mode_Out_PP;
    gpio_initsources.GPIO_Speed=GPIO_Speed_2MHz;

    //void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
    GPIO_Init(GPIOG,&gpio_initsources);
}

串口3中断服务函数:

void USART3_IRQHandler(void)
{
    u8 data=0;
    //接收数据--接收中断
    if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)
    {
        USART_ClearITPendingBit(USART3,USART_IT_RXNE);
        //用于接收ESP8266的数据
        rxbuff[usart_count++]=USART_ReceiveData(USART3);
        //打印ESP8266的数据到串口助手上
        USART1->DR=USART_ReceiveData(USART3);
//        printf("0000\r\n");
    }
    
    if(USART_GetITStatus(USART3,USART_IT_IDLE)==SET)
    {
//        rxbuff[rx_count++]=USART_ReceiveData(USART3);//清除数据
        
        over_flag=1;//一旦进入空闲中断,置1,本次传输结束
        rx_count=usart_count;//没有用
        usart_count=0;
        data=USART_ReceiveData(USART3);//清空缓存区
//        printf("11111\r\n");
        USART_ClearITPendingBit(USART3,USART_IT_IDLE);
    }
}

数据发送部分:

//发送单个字节函数
void USART3_SendData(char data)
{
    USART_SendData(USART3,data);
        
    /* 等待发送数据寄存器为空 */
    while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);    
    
}

void Usart3_SendStr(char *str)
{
    int i=0;
    while(*(str+i)!='\0')
    {
        USART3_SendData(*(str+i));
        i++;
    }
    
     while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET)
  {}
    
}

ESP8266每次上电的时候需要复位一下:

u8 Esp8266_AT_test(void)
{
    //"AT\r\n"
    char count=0;
    GPIO_SetBits ( GPIOG, GPIO_Pin_13 );
    GPIO_SetBits ( GPIOG, GPIO_Pin_14 );
  printf("\r\nAT测试.....\r\n");
    delay_ms ( 2000 );
    while ( count < 10 )
    {
    printf("\r\nAT测试次数 %d......\r\n", count);
        if( esp8266_SendCmd ( "AT\r\n", "OK",NULL,500) )
    {
      printf("\r\nAT测试启动成功 %d......\r\n", count);
      return 1;
    }
        //复位以下
        GPIO_ResetBits ( GPIOG, GPIO_Pin_14 );
      delay_ms ( 500 ); 
      GPIO_SetBits ( GPIOG, GPIO_Pin_14 );
        ++ count;
    }
  return 0;
}

发送AT指令的函数:

1、strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。
2、找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址;
3、如果未找到所搜索的字符串,则返回NULL。
uint8_t  esp8266_SendCmd(char *ctl_cmd,char *ret01,char *ret02,uint32_t time)
{
    uint8_t tim=time;
    memset(rxbuff,0,sizeof(rxbuff));
    //发送数据
    Usart3_SendStr(ctl_cmd);
    delay_ms(time);
    //接收数据
    while(tim--)
    {
        delay_ms(100);
            if(over_flag==1)//代表进入了空闲中断,本次接收数据完成
        {
            over_flag=0;

            tim=0;
            if ( ( ret01 != 0 ) && ( ret02 != 0 ) )        
        return ( ( bool ) strstr ( rxbuff, ret01 ) || 
                         ( bool ) strstr ( rxbuff, ret02 ) ); 
     
        else if ( ret01 != 0 )
            return ( ( bool ) strstr ( rxbuff, ret01 ) );
        
        else
            return ( ( bool ) strstr ( rxbuff, ret02 ) );
            
        }
//        memset(rxbuff,0,sizeof(rxbuff));
    }
    
    //发送完成之后,等待接收数据,比较返回值的内容
    return 0;
    
}

主函数中的配置:(联网流程)

esp8266_Init();
    ESP8266_IO_Config();
    printf("底层配置初始化完成\r\n");

    Esp8266_AT_test();
    

    delay_ms(3000);


    
    printf("配置联网模式\r\n");
    
while(!esp8266_SendCmd("AT+CWMODE=1\r\n","OK",NULL,300))
{}
    
    
    printf("配置热点\r\n");
sprintf(buff,"AT+CWJAP=\"%s\",\"%s\"\r\n",WIFI_ID,WIFI_PW);
while(!esp8266_SendCmd(buff,"OK",NULL,1000))
{}
    
    

    printf("配置服务器端\r\n");
    memset(buff,0,sizeof(buff));
    sprintf(buff,"AT+CIPSTART=\"TCP\",\"172.20.10.4\",%d\r\n",WIFI_PORT);
while(!esp8266_SendCmd(buff,"OK",NULL,1000))
{}
    
    
    printf("配置透传\r\n");
while(!esp8266_SendCmd("AT+CIPMODE=1\r\n","OK",NULL,500))
{}
    printf("收发数据\r\n");
    
while(!esp8266_SendCmd("AT+CIPSEND\r\n",">",NULL,10000))
{}

网络部分:

服务器端的配置:

完整配置:

#include "esp8266.h"
#include "stdio.h"
#include "string.h"
#include "delay.h"
#include "stdlib.h"
#include "stdbool.h"
char rxbuff[256]={0};
uint8_t rx_count=0; 
uint8_t usart_count=0;
uint8_t over_flag=0;


void esp8266_Init(void)
{
    GPIO_InitTypeDef GPIOInitTypeDef;
    USART_InitTypeDef USARTInitTypeDef;
    //打开时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
    //配置PB10--TX PB11--RX
    //PB10--复用推挽输出
    GPIOInitTypeDef.GPIO_Pin=GPIO_Pin_10;
    GPIOInitTypeDef.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIOInitTypeDef.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIOInitTypeDef);
    //PB11--浮空
    GPIOInitTypeDef.GPIO_Pin=GPIO_Pin_11;
    GPIOInitTypeDef.GPIO_Mode=GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB,&GPIOInitTypeDef);
    //usart3的配置
    USARTInitTypeDef.USART_BaudRate=115200;
    USARTInitTypeDef.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
    USARTInitTypeDef.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
    USARTInitTypeDef.USART_Parity=USART_Parity_No;
    USARTInitTypeDef.USART_StopBits=USART_StopBits_1;
    USARTInitTypeDef.USART_WordLength=USART_WordLength_8b;
    USART_Init(USART3,&USARTInitTypeDef);
    //配置中断
    //设置空闲中断和接收中断
    USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
    USART_ITConfig(USART3,USART_IT_IDLE,ENABLE);
    
    //

    NVIC_SetPriority(USART3_IRQn,0);//占先优先级:1 次级优先级:1 
    NVIC_EnableIRQ(USART3_IRQn);
    USART_Cmd(USART3,ENABLE);

}
void ESP8266_IO_Config(void)
{
GPIO_InitTypeDef gpio_initsources;
    //打开时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);
gpio_initsources.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14;
gpio_initsources.GPIO_Mode=GPIO_Mode_Out_PP;
gpio_initsources.GPIO_Speed=GPIO_Speed_2MHz;

    //void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
    GPIO_Init(GPIOG,&gpio_initsources);
}




void USART3_IRQHandler(void)
{
    u8 data=0;
    //接收数据--接收中断
    if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)
    {
        USART_ClearITPendingBit(USART3,USART_IT_RXNE);
        //用于接收ESP8266的数据
        rxbuff[usart_count++]=USART_ReceiveData(USART3);
        //打印ESP8266的数据到串口助手上
        USART1->DR=USART_ReceiveData(USART3);
//        printf("0000\r\n");
    }
    
    if(USART_GetITStatus(USART3,USART_IT_IDLE)==SET)
    {
//        rxbuff[rx_count++]=USART_ReceiveData(USART3);//清除数据
        
        over_flag=1;//一旦进入空闲中断,置1,本次传输结束
        rx_count=usart_count;//没有用
        usart_count=0;
        data=USART_ReceiveData(USART3);//清空缓存区
//        printf("11111\r\n");
        USART_ClearITPendingBit(USART3,USART_IT_IDLE);
    }
}

void esp8266_Analysis(void)
{
    int i=0;
    if(over_flag==1)
    {
        printf("000000\r\n");
        over_flag=0;
        //开始处理数据
//        for(i=0;i<rx_count;i++)
        printf("rx_data:%s\r\n",rxbuff);
    }
    memset(rxbuff,0,sizeof(rxbuff));
}


//发送单个字节函数
void USART3_SendData(char data)
{
    USART_SendData(USART3,data);
        
    /* 等待发送数据寄存器为空 */
    while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);    
    
}

void Usart3_SendStr(char *str)
{
    int i=0;
    while(*(str+i)!='\0')
    {
        USART3_SendData(*(str+i));
        i++;
    }
    
     while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET)
  {}
    
}

//发送--AT+.....
uint8_t sendcou=0;
//AT
//回复:OK
//time--每次发送数据等待接受的时间

uint8_t  esp8266_SendCmd(char *ctl_cmd,char *ret01,char *ret02,uint32_t time)
{
    uint8_t tim=time;
    memset(rxbuff,0,sizeof(rxbuff));
    //发送数据
    Usart3_SendStr(ctl_cmd);
    delay_ms(time);
    //接收数据
    while(tim--)
    {
        delay_ms(100);
            if(over_flag==1)//代表进入了空闲中断,本次接收数据完成
        {
            over_flag=0;

            tim=0;
            if ( ( ret01 != 0 ) && ( ret02 != 0 ) )        
        return ( ( bool ) strstr ( rxbuff, ret01 ) || 
                         ( bool ) strstr ( rxbuff, ret02 ) ); 
     
        else if ( ret01 != 0 )
            return ( ( bool ) strstr ( rxbuff, ret01 ) );
        
        else
            return ( ( bool ) strstr ( rxbuff, ret02 ) );
            
        }
//        memset(rxbuff,0,sizeof(rxbuff));
    }
    
    //发送完成之后,等待接收数据,比较返回值的内容
    return 0;
    
}
u8 Esp8266_AT_test(void)
{
    //"AT\r\n"
    char count=0;
    GPIO_SetBits ( GPIOG, GPIO_Pin_13 );
    GPIO_SetBits ( GPIOG, GPIO_Pin_14 );
  printf("\r\nAT测试.....\r\n");
    delay_ms ( 2000 );
    while ( count < 10 )
    {
    printf("\r\nAT测试次数 %d......\r\n", count);
        if( esp8266_SendCmd ( "AT\r\n", "OK",NULL,500) )
    {
      printf("\r\nAT测试启动成功 %d......\r\n", count);
      return 1;
    }
        //复位以下
        GPIO_ResetBits ( GPIOG, GPIO_Pin_14 );
      delay_ms ( 500 ); 
      GPIO_SetBits ( GPIOG, GPIO_Pin_14 );
        ++ count;
    }
  return 0;
}

主函数:

#include "stm32f10x.h"   // 相当于51单片机中的  #include <reg51.h>
#include "my_usart1.h"
#include "my_key.h"
#include "delay.h"
#include "my_tim.h"
#include "my_dma.h"
#include "esp8266.h"
#include "string.h"

#define WIFI_ID  "WLL001"
#define WIFI_PW  "123456789"
#define WIFI_PORT  8087

#define LED1(x) x?(GPIOB->ODR &=~(0X01<<5)):(GPIOB->ODR |=(0X01<<5))
void Led_Config(void);
void delay_tim(u32 tim);
void led_Breath(void);

int main(void)
{
    char buff[256]={0};
    // 来到这里的时候,系统的时钟已经被配置成72M。
    NVIC_SetPriorityGrouping(6);//0---7  占先优先级--7bit 次级优先级4--6bit
    systick_Init();
    Led_Config();
    usart1_Config(115200);
//    key_Config();
//    key_Interrupt_Cfg();
//    tim3_Ch2_Config();
//    DMA1_Config();
//    printf("底层配置初始化完成\r\n");
//    LED1(1);
    esp8266_Init();
    ESP8266_IO_Config();//pG13  PG14
    printf("底层配置初始化完成\r\n");

    Esp8266_AT_test();//复位

    delay_ms(3000);

    /*
    AT
AT+CWMODE= 1  //客户端
AT+CWJAP="WLL001","123456789"    //
AT+CIPMUX=0  //0--单链接

AT+CIPSTART1
="TCP","120.76.100.197",10002  //设置服务器IP端口
AT+CIPMODE=1  //透传模式

AT+CIPSEND     
>            //收发数据
    */
    printf("配置联网模式\r\n");
while(!esp8266_SendCmd("AT+CWMODE=1\r\n","OK",NULL,300))
{}
    
    
    printf("配置热点\r\n");
sprintf(buff,"AT+CWJAP=\"%s\",\"%s\"\r\n",WIFI_ID,WIFI_PW);
while(!esp8266_SendCmd(buff,"OK",NULL,1000))
{}
    
    printf("配置服务器端\r\n");
    memset(buff,0,sizeof(buff));
    sprintf(buff,"AT+CIPSTART=\"TCP\",\"192.168.137.1\",%d\r\n",WIFI_PORT);
while(!esp8266_SendCmd(buff,"OK",NULL,1000))
{}
    
    printf("配置透传\r\n");
while(!esp8266_SendCmd("AT+CIPMODE=1\r\n","OK",NULL,500))
{}
    printf("收发数据\r\n");
    
while(!esp8266_SendCmd("AT+CIPSEND\r\n",">",NULL,10000))
{}
    while(1)
    {
//    esp8266_SendCmd("AT\r\n","OK",NULL,300);
    esp8266_Analysis();
        
        Usart3_SendStr("hello world");
//        Get_Data();
        delay_ms(1000);
        LED1(1);
        delay_ms(1000);
        LED1(0);
        delay_ms(1000);
        
        
        
    }
}
void Led_Config(void)
{
    //时钟
    RCC->APB2ENR |=0X01<<3;
    //配置通用推挽输出
    GPIOB->CRL &=~(0X0F<<20);//清零
    GPIOB->CRL |=0x01<<20;//通用推挽输出--10MHZ
}

void led_Breath(void)
{
    u32 i=0;
    for(i=0;i<1500;i++)
    {
        LED1(1);
        delay_us(i);
        LED1(0);
        delay_us(1500-i);
    }
    for(i=0;i<1500;i++)
    {
        LED1(1);
        delay_us(1500-i);
        LED1(0);
        delay_us(i);
        
    }
}


void delay_tim(u32 tim)
{
    while(tim--);
}

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

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

相关文章

80,【4】BUUCTF WEB [SUCTF 2018]MultiSQL

53&#xff0c;【3】BUUCTF WEB october 2019 Twice SQLinjection-CSDN博客 上面这个链接是我第一次接触二次注入 这道题也涉及了 对二次注入不熟悉的可以看看 BUUCTF出了点问题&#xff0c;打不开&#xff0c;以下面这两篇wp作为学习对象 [SUCTF 2018]MultiSQL-CSDN博客 …

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm监控配置

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm监控配置 1.Prometheus部署1.2.Prometheus修改默认端口 2.grafana可视化页面部署3.alertmanager部署4.监控配置4.1.主机监控node-exporter4.2.监控mysql数据库mysqld_exporter4.3.监控mongod数据库mongodb_expo…

问题排查 - TC397 CORE2 50MS/100MS任务不运行

1、问题描述 CORE2 的任务运行次数的计数值OsTask_100ms_Core2 - task_cnt[12]、OsTask_50ms_Core2 - task_cnt[16]不在累加&#xff0c;但是其他任务OsAlarm_1ms_Core2、OsAlarm_5ms_Core2、OsAlarm_10ms_Core2、OsAlarm_20ms_Core2 任务计数值累加正常。 如果是任务栈溢出&a…

Spring FatJar写文件到RCE分析

背景 现在生产环境部署 spring boot 项目一般都是将其打包成一个 FatJar&#xff0c;即把所有依赖的第三方 jar 也打包进自身的 app.jar 中&#xff0c;最后以 java -jar app.jar 形式来运行整个项目。 运行时项目的 classpath 包括 app.jar 中的 BOOT-INF/classes 目录和 BO…

百度APP iOS端磁盘优化实践(上)

01 概览 在APP的开发中&#xff0c;磁盘管理已成为不可忽视的部分。随着功能的复杂化和数据量的快速增长&#xff0c;如何高效管理磁盘空间直接关系到用户体验和APP性能。本文将结合磁盘管理的实践经验&#xff0c;详细介绍iOS沙盒环境下的文件存储规范&#xff0c;探讨业务缓…

蓝桥杯之c++入门(一)【第一个c++程序】

目录 前言一、第⼀个C程序1.1 基础程序1.2 main函数1.3 字符串1.4 头文件1.5 cin 和 cout 初识1.6 名字空间1.7 注释 二、四道简单习题&#xff08;点击跳转链接&#xff09;练习1&#xff1a;Hello,World!练习2&#xff1a;打印飞机练习3&#xff1a;第⼆个整数练习4&#xff…

14-6-1C++STL的list

(一&#xff09;list容器的基本概念 list容器简介&#xff1a; 1.list是一个双向链表容器&#xff0c;可高效地进行插入删除元素 2.list不可以随机存取元素&#xff0c;所以不支持at.(pos)函数与[ ]操作符 &#xff08;二&#xff09;list容器头部和尾部的操作 list对象的默…

【AI论文】Sigma:对查询、键和值进行差分缩放,以实现高效语言模型

摘要&#xff1a;我们推出了Sigma&#xff0c;这是一个专为系统领域设计的高效大型语言模型&#xff0c;其独特之处在于采用了包括DiffQKV注意力机制在内的新型架构&#xff0c;并在我们精心收集的系统领域数据上进行了预训练。DiffQKV注意力机制通过根据查询&#xff08;Q&…

InceptionV1_V2

目录 不同大小的感受野去提取特征 经典 Inception 网络的设计思路与运行流程 背景任务&#xff1a;图像分类&#xff08;以 CIFAR-10 数据集为例&#xff09; Inception 网络的设计思路 Inception 网络的运行流程 打个比方 多个损失函数的理解 1. 为什么需要多个损失函数&#…

ORB-SLAM2源码学习:Initializer.cc⑧: Initializer::CheckRT检验三角化结果

前言 ORB-SLAM2源码学习&#xff1a;Initializer.cc⑦: Initializer::Triangulate特征点对的三角化_cv::svd::compute-CSDN博客 经过上面的三角化我们成功得到了三维点&#xff0c;但是经过三角化成功的三维点并不一定是有效的&#xff0c;需要筛选才能作为初始化地图点。 …

【ArcGIS微课1000例】0141:提取多波段影像中的单个波段

文章目录 一、波段提取函数二、加载单波段导出问题描述:如下图所示,img格式的时序NDVI数据有24个波段。现在需要提取某一个波段,该怎样操作? 一、波段提取函数 首先加载多波段数据。点击【窗口】→【影像分析】。 选择需要处理的多波段影像,点击下方的【添加函数】。 在多…

一文大白话讲清楚webpack基本使用——17——Tree Shaking

文章目录 一文大白话讲清楚webpack基本使用——17——Tree Shaking1. 建议按文章顺序从头看&#xff0c;一看到底&#xff0c;豁然开朗2. 啥叫Tree Shaking3. 什么是死代码&#xff0c;怎么来的3. Tree Shaking的流程3.1 标记3.2 利用Terser摇起来 4. 具体使用方式4.1 适用前提…

PyCharm配置Python环境

1、打开PyCharm项目 可以从File-->Open-->选择你的项目路径-->OK&#xff0c;或者直接点击Open&#xff0c;找到项目路径-->OK&#xff0c;如图所示(点击Ok后可能有下面的弹窗&#xff0c;选择“Trust Project”即可&#xff0c;然后选择“New Window”打开项目) …

c#配置config文件

1&#xff0c;引用命名空间 Configuration 及配置信息

RDMA 工作原理 | 支持 RDMA 的网络协议

注&#xff1a;本文为 “RDMA” 相关文章合辑。 英文引文机翻未校。 图片清晰度受引文所限。 Introduction to Remote Direct Memory Access (RDMA) Written by: Dotan Barak on March 31, 2014.on February 13, 2015. What is RDMA? 什么是 RDMA&#xff1f; Direct me…

01-硬件入门学习/嵌入式教程-CH340C使用教程

前言 CH340C广泛应用于DIY项目和嵌入式开发中&#xff0c;用于USB数据转换和串口通信。本文将详细介绍CH340C的基本功能、引脚接线及使用方法。 CH340C简介 CH340C是一款USB转TTL电平转换器&#xff0c;可以将电脑的USB数据转换成串口数据&#xff0c;方便与单片机&#xff…

STM32——LCD

一、引脚配置 查看引脚 将上述引脚都设置为GPIO_Output 二、导入驱动文件 将 LCD 驱动的 Inc 以及 Src 中的 fonts.h,lcd.h 和 lcd.c 导入到自己工程的驱动文件中。 当然&#xff0c;后面 lcd 的驱动学习可以和 IMX6U 一块学。 三、LCD函数 void LCD_Clear(u16 Color); 功能…

操作系统(Linux Kernel 0.11Linux Kernel 0.12)解读整理——内核初始化(main init)之内存的划分

前言 MMU&#xff1a;内存管理单元(Memory Management Unit)完成的工作就是虚拟地址到物理地址的转换&#xff0c;可以让系统中的多个程序跑在自己独立的虚拟地址空间中&#xff0c;相互不会影响。程序可以对底层的物理内存一无所知&#xff0c;物理地址可以是不连续的&#x…

.NET MAUI进行UDP通信(二)

上篇文章有写过一个简单的demo&#xff0c;本次对项目进行进一步的扩展&#xff0c;添加tabbar功能。 1.修改AppShell.xaml文件&#xff0c;如下所示&#xff1a; <?xml version"1.0" encoding"UTF-8" ?> <Shellx:Class"mauiDemo.AppShel…

社区养老服务平台的设计与实现(代码+数据库+LW)

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#…