STM32CubeMX-H7-19-ESP8266通信(中)--单片机控制ESP8266实现TCP地址通信

news2025/7/26 9:44:26

前言

        上篇文章我们已经能够使用串口助手实现esp8266的几种通信,接下来我们使用单片机控制实现。这篇文章会附带教程,增加.c和,.h,把串口和定时器放到对应的编号,然后调用初始化就可以使用了。

先讲解,然后末尾再放源码,也可以先看源码再看讲解

一.串口的不定时长接收

        因为esp8266发送的信息是没有帧头和帧位的,所以我们只能用这个方法,串口选定我们对应连接,我这里选择串口2,串口一用于重定向,打印调试信息(具体可以看我以前串口重定向的教程https://blog.csdn.net/m0_74211379/article/details/145366555?spm=1001.2014.3001.5502)。

        这里还需要使用一个1ms的定时器中断,这个方法也可以看我之前的文章https://blog.csdn.net/m0_74211379/article/details/146238875?spm=1001.2014.3001.5502

        然后开始讲用法

uint8_t esp8266_buffer[128],esp8266_buff[1],esp8266_len=0,esp8266_time=0,esp8266_flag=0;
char esp8266_wait[100];

这个是变量定义,全局的

要放在串口中断

void ESP8266_UART_Handler(void)
{
    esp8266_buffer[esp8266_len++]=esp8266_buff[0];
    esp8266_time=0;
    HAL_UART_Receive_IT(ESP8266_UART,(uint8_t *)esp8266_buff,1);
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
		if(huart->Instance == USART2)		
    {	 
        ESP8266_UART_Handler();
    }			
}

放在1ms定时器中断

void ESP8266_Time(void)
{
    esp8266_time++;
    if((esp8266_time>10)&&(esp8266_len>0))
    {
        esp8266_buffer[esp8266_len]=0;
        ESP8266_Change();
        memset(esp8266_buffer, '\0', sizeof(esp8266_buffer));
        esp8266_len=0;
        esp8266_time=0; 
    } 
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM2)
    {
			 ESP8266_Time();
		}
}

 

处理获取一次的数据

void ESP8266_Change()
{
  	printf("%s\r\n",esp8266_buffer);
    if(contains_OK(esp8266_buffer,esp8266_wait))
    {
        esp8266_flag=1;
    }
    ESP8266_IPD(esp8266_buffer);
}

二.WiFi名称密码还有TCP地址和端口号

const char ESP8266_WIFI_SSID[]="lty";
const char ESP8266_WIFI_PassWord[]="2395832518";
const char ESP8266_WIFI_TCP_IP[]="112.125.89.8";
const char ESP8266_WIFI_TCP_PORT[]="45655";

三.初始化

void ESP8266_Init(void)
{
		HAL_TIM_Base_Start_IT(ESP8266_TIM);
    HAL_UART_Receive_IT(ESP8266_UART,(uint8_t *)esp8266_buff,1);
}

四.发送指令函数

这里对需要连接的指令进行封装,第一个是发送的指令,第二个是接收到什么指令才能继续


void ESP8266_CMD(uint8_t cmd,uint16_t leng)
{
	char buffer[100];
    switch(cmd)
    {
    	   case 0:
				sprintf(buffer,"AT+RST\r\n");
                sprintf(esp8266_wait,"OK");   
            break;
           case 1:
                sprintf(buffer,"AT\r\n");
                sprintf(esp8266_wait,"OK");
						break;	
			case 2:
                sprintf(buffer,"AT+CWMODE=1\r\n");
                sprintf(esp8266_wait,"OK");
						break;	
			case 3:
                sprintf(buffer,"AT+CWJAP=\"%s\",\"%s\"\r\n",ESP8266_WIFI_SSID,ESP8266_WIFI_PassWord);
                sprintf(esp8266_wait,"WIFI GOT IP");
						break;	
			case 4:
                sprintf(buffer,"AT+CWJAP?\r\n");
                sprintf(esp8266_wait,"OK");
						break;	
            case 5:
                sprintf(buffer,"AT+CIPMUX=0\r\n");
                  sprintf(esp8266_wait,"OK");
                        break;    
            case 6:
                sprintf(buffer,"AT+CIPSTART=\"TCP\",\"%s\",%s\r\n",ESP8266_WIFI_TCP_IP,ESP8266_WIFI_TCP_PORT);
						  sprintf(esp8266_wait,"OK");
                        break;    
            case 7:
                sprintf(buffer,"AT+CIPSEND=%d\r\n",leng);
								sprintf(esp8266_wait,"");
                        break;    
            case 8:
                sprintf(buffer,"");
								sprintf(esp8266_wait,"SEND OK");
                        break;
    }
    ESP8266_commom(buffer);
}

五.等待发送指令函数

这个函数用于检测缓冲区是否有接收完成的指令,如果没有,那么超过200ms就会重新发送一次指令,直到缓冲区有接受到指令的字符串文本

void ESP8266_commom(const char *cmd)
{
    HAL_UART_Transmit(ESP8266_UART,(uint8_t *)cmd,strlen(cmd),100);
    esp8266_flag=0;
    while (esp8266_flag==0){
    if (esp8266_time>200)
    {
       HAL_UART_Transmit(ESP8266_UART,(uint8_t *)cmd,strlen(cmd),100);
       printf("%s time out\r\n",cmd);
       esp8266_time=0;
        }
    }
}

int contains_OK(const char *str, const char *substr) {
    if (strstr(str, substr) != NULL) {
        return 1; // 包含 
    }
    return 0; // 不包含 
}

六.连接上TCP

上面的弄好后,进行一次循环就可以连接上

void ESP8266_CONNECT_TO_TCP()
{
        for(uint8_t i = 0; i < 7; i++)
    {  
         ESP8266_CMD(i,0);
		printf("cmd=%d\r\n",i);
		HAL_Delay(500);
	}
}

七.往TCP网络发送消息

也是对原有函数的封装,先获取要发送的长度,然后再发送

void ESP8266_send_TCP(const char *data)
{
	ESP8266_CMD(7,strlen(data));
    HAL_UART_Transmit(ESP8266_UART,(uint8_t *)data,strlen(data),100);
    ESP8266_CMD(8,0);
}

八.接收TCP发送来的消息

根据我实测的话,虽然串口显示第一个是+,但是打印显示是在后两个位置,所以我做一个偏移


void ESP8266_IPD(const char *data)
{
    char *p=data;
    uint8_t leng=0;
    char hand[256];

	if(strlen(data)>6)
	//printf("data[0]=%c,data[1]=%c,data[2]=%c,data[3]=%c,data[4]=%c\r\n",data[0],data[1],data[2],data[3],data[4]);
    if (data[2] == '+' && data[3] == 'I' && data[4] == 'P' && data[5] == 'D')
    {
        p+=6; 

        while (*p != ':') {
            leng = leng * 10 + *p - '0';
            p++;	
        }
        p++; 
        strncpy(hand, p, leng); 
        hand[leng] = '\0'; 
        printf("Received data: %s\r\n", hand);
    }
}

九.H文件的修改

把串口和定时器编号修改对九可以了

#ifndef HC_TR_H
#define HC_TR_H
 
#include "main.h"
 
#define ESP8266_UART    &huart2
#define ESP8266_TIM    &htim2
void ESP8266_Change();
void ESP8266_Time(void);
void ESP8266_Init(void);
void ESP8266_UART_Handler(void);
void ESP8266_CMD(uint8_t cmd,uint16_t leng);
int contains_OK(const char *str, const char *substr);
void ESP8266_commom(const char *cmd);
void ESP8266_CONNECT_TO_TCP();
void ESP8266_send_TCP(const char *data);
void ESP8266_IPD(const char *data);

#endif /* HC_TR_H */

十.功能测试及使用教程

首先我们手机开热点,2.4G,5G的不行

根据网站合宙 TCP/UDP web工具 (luatos.com)

获取的填入

然后在主函数添加头文件后,直接写

初始化加连接WIFI,还有发送两次数据

	ESP8266_Init();
ESP8266_CONNECT_TO_TCP();
ESP8266_send_TCP("hello\r\n");
ESP8266_send_TCP("yes ok\r\n");

然后编译烧录

串口助手打印的数据

AT+RST

OK
WIFI DISCONNECT

cmd=0
(5d6f877)
SPI Speed : 40MHz
SPI Mode : DOUT
SPI Flash Size & Map: 8Mbit(512KB+512KB)
jump to run user1 @ 1000


?rls髇l


ready

AT
 time out
AT
AT

busy p...

OK

cmd=1
AT+CWMODE=1
 time out
AT+CWMODE=1
AT+CWMODE=1

busy p...

OK

cmd=2
AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...

AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"
 time out
AT+CWJAP="lty2","2395832518"

busy p...
AT+CWJAP="lty2","2395832518"

busy p...
AT+CWJAP="lty2","2395832518"

busy p...
AT+CWJAP="lty2","2395832518"

busy p...
AT+CWJAP
cmd=3
WIFI CONNECTED

AT+CWJAP?
 time out
AT+CWJAP?

busy p...
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

WIFI GOT IP

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...

AT+CWJAP?
 time out
AT+CWJAP?

busy p...


OK

cmd=4
AT+CIPMUX=0
 time out
AT+CIPMUX=0
AT+CIPMUX=0

busy p...

OK

cmd=5
AT+CIPSTART="TCP","112.125.89.8",42137
 time out
AT+CIPSTART="TCP","112.125.89.8",42137
AT+CIPSTART="TCP","112.125.89.8",42137

busy p...

CONNECT

OK

cmd=6
AT+CIPSEND=7
 time out
AT+CIPSEND=7
AT+CIPSEND=7

busy p...

OK
> 

Recv 7 bytes


SEND OK

AT+CIPSEND=8

OK
> 

Recv 8 bytes


SEND OK


+IPD,7:hello

+IPD,8:yes ok

Received data: hello

+IPD,8:yes ok

然后我们去网站上发送

在串口助手上可以看见成功接收了

十一.完整源码

esp8266.c

#include "esp8266.h"
#include "tim.h"
#include "gpio.h"
#include "usart.h"
#include "stdio.h"
#include "string.h"

// 定义ESP8266相关的缓冲区、长度、时间、标志位和等待响应字符串
uint8_t esp8266_buffer[128],esp8266_buff[1],esp8266_len=0,esp8266_time=0,esp8266_flag=0;
char esp8266_wait[100];

// 定义ESP8266连接的WiFi信息和TCP服务器信息
const char ESP8266_WIFI_SSID[]="lty2";
const char ESP8266_WIFI_PassWord[]="2395832518";
const char ESP8266_WIFI_TCP_IP[]="112.125.89.8";
const char ESP8266_WIFI_TCP_PORT[]="42137";

// 初始化ESP8266模块,启动定时器中断和UART接收中断
void ESP8266_Init(void)
{
    HAL_TIM_Base_Start_IT(ESP8266_TIM);
    HAL_UART_Receive_IT(ESP8266_UART,(uint8_t *)esp8266_buff,1);
}

// 发送ESP8266命令,根据不同的命令编号和数据长度构造命令
void ESP8266_CMD(uint8_t cmd,uint16_t leng)
{
    char buffer[100];
    switch(cmd)
    {
        case 0:
            sprintf(buffer,"AT+RST\r\n");
            sprintf(esp8266_wait,"OK");   
            break;
        case 1:
            sprintf(buffer,"AT\r\n");
            sprintf(esp8266_wait,"OK");
            break;	
        case 2:
            sprintf(buffer,"AT+CWMODE=1\r\n");
            sprintf(esp8266_wait,"OK");
            break;	
        case 3:
            sprintf(buffer,"AT+CWJAP=\"%s\",\"%s\"\r\n",ESP8266_WIFI_SSID,ESP8266_WIFI_PassWord);
            sprintf(esp8266_wait,"WIFI GOT IP");
            break;	
        case 4:
            sprintf(buffer,"AT+CWJAP?\r\n");
            sprintf(esp8266_wait,"OK");
            break;	
        case 5:
            sprintf(buffer,"AT+CIPMUX=0\r\n");
            sprintf(esp8266_wait,"OK");
            break;    
        case 6:
            sprintf(buffer,"AT+CIPSTART=\"TCP\",\"%s\",%s\r\n",ESP8266_WIFI_TCP_IP,ESP8266_WIFI_TCP_PORT);
            sprintf(esp8266_wait,"OK");
            break;    
        case 7:
            sprintf(buffer,"AT+CIPSEND=%d\r\n",leng);
            sprintf(esp8266_wait,"");
            break;    
        case 8:
            sprintf(buffer,"");
            sprintf(esp8266_wait,"SEND OK");
            break;
    }
    ESP8266_commom(buffer);
}

// 通用的ESP8266命令发送函数,发送命令并等待响应,超时会重新发送
void ESP8266_commom(const char *cmd)
{
    HAL_UART_Transmit(ESP8266_UART,(uint8_t *)cmd,strlen(cmd),100);
    esp8266_flag=0;
    while (esp8266_flag==0){
        if (esp8266_time>200)
        {
            HAL_UART_Transmit(ESP8266_UART,(uint8_t *)cmd,strlen(cmd),100);
            printf("%s time out\r\n",cmd);
            esp8266_time=0;
        }
    }
}

// 连接ESP8266到TCP服务器,依次发送多个初始化命令
void ESP8266_CONNECT_TO_TCP()
{
    for(uint8_t i = 0; i < 7; i++)
    {  
        ESP8266_CMD(i,0);
        printf("cmd=%d\r\n",i);
        HAL_Delay(500);
    }
}

// 通过ESP8266向TCP服务器发送数据
void ESP8266_send_TCP(const char *data)
{
    ESP8266_CMD(7,strlen(data));
    HAL_UART_Transmit(ESP8266_UART,(uint8_t *)data,strlen(data),100);
    ESP8266_CMD(8,0);
}

// 检查字符串中是否包含指定子字符串
int contains_OK(const char *str, const char *substr) {
    if (strstr(str, substr) != NULL) {
        return 1; // 包含指定子字符串
    }
    return 0; // 不包含指定子字符串
}

// 处理ESP8266接收的数据,检查是否有期望响应并调用IPD处理函数
void ESP8266_Change()
{
    printf("%s\r\n",esp8266_buffer);
    if(contains_OK(esp8266_buffer,esp8266_wait))
    {
        esp8266_flag=1;
    }
    ESP8266_IPD(esp8266_buffer);
}

// 解析ESP8266接收到的IPD数据
void ESP8266_IPD(const char *data)
{
    char *p=data;
    uint8_t leng=0;
    char hand[256];

    if(strlen(data)>6)
        //printf("data[0]=%c,data[1]=%c,data[2]=%c,data[3]=%c,data[4]=%c\r\n",data[0],data[1],data[2],data[3],data[4]);
        if (data[2] == '+' && data[3] == 'I' && data[4] == 'P' && data[5] == 'D')
        {
            p+=6; 

            while (*p != ':') {
                leng = leng * 10 + *p - '0';
                p++;	
            }
            p++; 
            strncpy(hand, p, leng); 
            hand[leng] = '\0'; 
            printf("Received data: %s\r\n", hand);
        }
}

// 处理ESP8266 UART接收中断,将接收到的数据存入缓冲区
void ESP8266_UART_Handler(void)
{
    esp8266_buffer[esp8266_len++]=esp8266_buff[0];
    esp8266_time=0;
    HAL_UART_Receive_IT(ESP8266_UART,(uint8_t *)esp8266_buff,1);
}

// 处理ESP8266定时器中断,超时后处理接收的数据并清空缓冲区
void ESP8266_Time(void)
{
    esp8266_time++;
    if((esp8266_time>10)&&(esp8266_len>0))
    {
        esp8266_buffer[esp8266_len]=0;
        ESP8266_Change();
        memset(esp8266_buffer, '\0', sizeof(esp8266_buffer));
        esp8266_len=0;
        esp8266_time=0; 
    } 
}

// UART接收完成回调函数,当USART2接收完成时调用ESP8266 UART处理函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART2)		
    {	 
        ESP8266_UART_Handler();
    }			
}

// 定时器周期溢出回调函数,当TIM2溢出时调用ESP8266时间处理函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM2)
    {
        ESP8266_Time();
    }
}


esp8266.h

#ifndef HC_TR_H
#define HC_TR_H
 
#include "main.h"
 
#define ESP8266_UART    &huart2
#define ESP8266_TIM    &htim2
void ESP8266_Change();
void ESP8266_Time(void);
void ESP8266_Init(void);
void ESP8266_UART_Handler(void);
void ESP8266_CMD(uint8_t cmd,uint16_t leng);
int contains_OK(const char *str, const char *substr);
void ESP8266_commom(const char *cmd);
void ESP8266_CONNECT_TO_TCP();
void ESP8266_send_TCP(const char *data);
void ESP8266_IPD(const char *data);

#endif 

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

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

相关文章

【汇编逆向系列】四、函数调用包含单个参数之Double类型-mmword,movsd,mulsd,addsd指令,总结汇编的数据类型

一、汇编代码 上一节开始&#xff0c;讲到了很多debug编译独有的汇编方式&#xff0c;为了更好的区分release的编译器优化和debug的区别&#xff0c;从本章节开始将会提供debug和release的汇编用作对比 Debugb编译 single_double_param:00000000000000A0: F2 0F 11 44 24 08…

【AI学习】wirelessGPT多任务无线基础模型摘要

收看了关于WirelessGPT多任务无线基础模型的演讲视频&#xff0c;边做一个记录。 应该说&#xff0c;在无线通信大模型的探索方面&#xff0c;有一个非常有益的尝试。 在沈学明院士带领下开展 https://www.chaspark.com/#/live/1125484184592834560

docker 部署redis集群 配置

docker的网络模式 网桥模式每次重启容器都有可能导致容器ip地址变化&#xff0c;需要固定ip的自己自定义网络&#xff0c;这里介绍的是默认网络模式 docker创建容器 docker run --name redis6379 -p 6379:6379 -p 16379:16379 -v /etc/redis/redis6379:/etc/redis -d --r…

Ansys Maxwell:线圈和磁体的静磁 3D 分析

本博客展示了如何在 Ansys Maxwell 中执行静磁 3D 分析&#xff0c;以计算载流线圈和永磁体之间相互作用产生的扭矩。在这个例子中&#xff0c;线圈中的电流产生一个沿 Y 轴指向的磁场&#xff0c;而永磁体沿 X 轴被磁化。这种配置导致围绕 Z 轴的扭矩。分步工作流程包括构建几…

【计算机网络】SDN

SDN这种新型网络体系结构的核心思想&#xff1a;把网络的控制层面与数据层面分离&#xff0c;而让控制层面利用软件来控制数据层面中的许多设备。 OpenFlow协议可以被看成是SDN体系结构中控制层面与数据层面之间的通信接口。 在SDN中取代传统路由器中转发表的是“流表”&…

成工fpga(知识星球号)——精品来袭

&#xff08;如需要相关的工程文件请关注知识星球&#xff1a;成工fpga&#xff0c;https://t.zsxq.com/DMeqH&#xff0c;关注即送200GB学习资料&#xff0c;链接已置顶&#xff01;&#xff09; 《孩子都能学会的FPGA》系列是成工完成的第一个系列&#xff0c;也有一年多的时…

spring中的@KafkaListener 注解详解

KafkaListener 是 Spring Kafka 提供的一个核心注解&#xff0c;用于标记一个方法作为 Kafka 消息的消费者。下面是对该注解的详细解析&#xff1a; 基本用法 KafkaListener(topics "myTopic", groupId "myGroup") public void listen(String message)…

NoSQL——Redis配置与优化

目录 关系型&非关系型数据库 一、核心原理对比‌ ‌二、核心特性对比‌ ‌三、关键区别剖析‌ ‌四、典型产品示例‌ ‌总结‌ Redis Redis核心原理 核心特性 技术意义 配置文件解析 1. 基础配置 2. 持久化配置 3. 内存管理 4. 高可用配置 5. 性能调优 6.…

CKA考试知识点分享(2)---ingress

CKA 版本&#xff1a;1.32 第二题是涉及ingress相关。本文不是题目&#xff0c;只是为了学习相关知识点做的实验。 1. 环境准备 需要准备一套K8S集群。 1.1 安装ingress-nginx 下载deploy文件&#xff1a; wget -O controller-v1.12.2.yaml https://raw.githubusercontent…

动态生成element-plus的scss变量;SCSS中实现动态颜色变体生成

文章目录 一、动态css变量1.生成内容2.动态生成css变量2.1新增_color-utils.scss&#xff08;不推荐&#xff09;2.2新增_color-utils.scss&#xff08;推荐&#xff09;2.3theme.scss引入使用 一、动态css变量 1.生成内容 在我们修改element-plus主题色时候&#xff0c;会自…

Linux 内核内存管理子系统全面解析与体系构建

一、前言: 为什么内存管理是核心知识 内存管理是 Linux 内核最核心也最复杂的子系统之一&#xff0c;其作用包括&#xff1a; 为软件提供独立的虚拟内存空间&#xff0c;实现安全隔离分配/回收物理内存资源&#xff0c;维持系统稳定支持不同类型的内存分配器&#xff0c;最优…

Tableau for mac 驱动

Tableau 驱动程序安装指南 对于希望在 Mac OS 上使用 Tableau 进行数据分析的用户来说&#xff0c;确保正确安装相应的驱动程序至关重要。Tableau 支持多种数据库连接方式&#xff0c;并提供官方文档指导如何设置这些连接。 安装适用于 Mac 的 JDBC 或 ODBC 驱动程序 为了使…

fast-reid部署

配置设置&#xff1a; 官方库链接&#xff1a; https://github.com/JDAI-CV/fast-reid# git clone https://github.com/JDAI-CV/fast-reid.git 安装依赖&#xff1a; pip install -r docs/requirements.txt 编译&#xff1a;切换到fastreid/evaluation/rank_cylib目录下&a…

大陆4D毫米波雷达ARS548调试

本文介绍了大陆ARS548毫米波雷达的调试与测试流程&#xff0c;主要包括以下内容&#xff1a; 设备参数&#xff1a;最大检测距离301m&#xff08;可调93-1514m&#xff09;&#xff0c;支持gPTP时间同步。 接线调试&#xff1a; Windows需使用USB-RJ45转换器 Linux可直接连接网…

大语言模型解析

1. Input Embedding embedding&#xff1a;将自然语言翻译成index 每个index对应一个embedding&#xff0c;embedding需要训练&#xff0c;embedding是一个数组

Java在word中指定位置插入图片。

Java使用&#xff08;Poi-tl&#xff09; 在word&#xff08;docx&#xff09;中指定位置插入图片 Poi-tl 简介Maven 依赖配置Poi-tl 实现原理与步骤1. 模板标签规范2.完整实现代码3.效果展示 Poi-tl 简介 Poi-tl 是基于 Apache POI 的 Java 开源文档处理库&#xff0c;专注于…

可视化图解算法48:有效括号序列

牛客网 面试笔试 TOP101 | LeetCode 20. 有效的括号 1. 题目 描述 给出一个仅包含字符(,),{,},[和],的字符串&#xff0c;判断给出的字符串是否是合法的括号序列 括号必须以正确的顺序关闭&#xff0c;"()"和"()[]{}"都是合法的括号序列&…

Continue 开源 AI 编程助手框架深度分析

Continue 开源 AI 编程助手框架深度分析 一、项目简介 Continue 是一个模块化、可配置、跨平台的开源 AI 编程助手框架&#xff0c;目标是让开发者能在本地或云端环境中&#xff0c;快速集成和使用自定义的 LLM 编程辅助工具。它通过支持 VS Code 与 JetBrains 等主流 IDE 插件…

MySQL技术内幕1:内容介绍+MySQL编译使用介绍

文章目录 1.整体内容介绍2.下载编译流程2.1 安装编译工具和依赖库2.2 下载编译 3.配置MySQL3.1 数据库初始化3.2 编辑配置文件3.3 启动停止MySQL3.4 登录并修改密码 1.整体内容介绍 MySQL技术系列文章将从MySQL下载编译&#xff0c;使用到MySQL各组件使用原理源码分析&#xf…

网络安全问题及对策研究

摘 要 网络安全问题一直是近年来社会乃至全世界十分关注的重要性问题&#xff0c;网络关乎着我们的生活&#xff0c;政治&#xff0c;经济等多个方面&#xff0c;致力解决网络安全问题以及给出行之有效的安全策略是网络安全领域的一大目标。 本论文简述了课题的开发背景&…