STM32网络通讯之CubeMX实现LWIP项目设计(十五)

STM32F407 系列文章 - ETH-LWIP-CubeMX(十五)


目录

前言

一、软件设计

二、CubeMX实现

1.配置前准备

2.CubeMX配置

1.ETH模块配置

2.时钟模块配置

3.中断模块配置

4.RCC及SYS配置

5.LWIP模块配置

3.生成代码

1.main文件

2.用户层源文件

3.用户层头文件

4.效果演示

总结


前言

一般对于许多嵌入式系统或单片机,在其资源受限的环境下,要想实现网络通讯,并保证资源的高效利用和稳定的网络通信,我们一般采用一种轻量级的网络协议lwIP。TI公司的STM32芯片一般都会自带一路以太网口,用于网络通讯,但因其内存资源受限,所以都用采用一种小型化、轻量级的lwIP网络协议,只需十几KB的RAM和大约40K的ROM即可运行,既可以在无操作系统环境下工作,也可以与各种操作系统配合使用,使其成为资源受限的嵌入式系统的理想选择。一般市场上所卖的板子都带这一功能的,需准备STM32F407开发板一块和网线一根。


一、软件设计

前面上一篇博文STM32之LWIP网络通讯设计介绍(十四)-CSDN博客讲述了对STM32实现LWIP网络通讯的前提性要求介绍,包含使用到的网络协议、MAC内核、PHY驱动芯片、通讯连接示意图、以及硬件电路原理设计图,为网络通讯软件开发提供了设计指导。今天将完成STM32网络通讯的软件设计,采用通过可视化工具STM32CubeMX完成对lwIP通讯的配置,一键化生成工程代码,这是博主比较推荐的一种方法,简便快捷。

二、CubeMX实现

‌STM32CubeMX是一个图形化配置工具,主要用于配置STM32微控制器和微处理器。它通过直观的图形用户界面,帮助用户选择STM32 MCU型号、配置引脚、设置系统时钟和外设参数,并生成相应的初始化C代码。这里对CubeMX可视化工具不做详细的介绍,改天会专门写篇文章介绍它。

1.配置前准备

在进行可视化工具CubeMX设置前,需要先了解处理器网络通讯的电路图实现,主要是了解到处理器使用到的IO引脚以及网络驱动芯片,根据上一篇文章介绍网络通讯设计-上(十四)(有提供stm32f407手册数据和YT8512C驱动芯片数据),线连接到处理器的IO引脚PC4、PC5、PG13、PG14、PG11、PC1、PA2、PA7、PD3,如下图所示。

2.CubeMX配置

打开CubeMX工具,如下所示。

1.ETH模块配置

上图,在右边Pinout View上面,根据电气原理图设置stm32相关IO引脚,如上图所示,设置完相关引脚后在上图左边ETH项,打开可以看到配置的相关引脚PC4、PC5、PG13、PG14、PG11、PC1、PA2、PA7、PD3如下所示。

在上图上,我们选择网络模式为RMII,根据YT8512C驱动芯片数据手册,MAC地址、PHY地址、PHY状态寄存器地址、PHY速度、PHY双工状态、以及PHY相关参数设置如下。

需要注意的是,在PHY使用型号上,我们也可以使用常见LAN8472芯片,选择它后,cube自动会帮你配置参数,不像自定义user PHY需要自己配置。

并使能Eth中断配置,如下。

根据电气设计图,设置处理器IO引脚PD3为ETH复位引脚,如下所示。

2.时钟模块配置

根据图纸参数,外部时钟为8MHz,处理器最高位168MHz,完成相关设置如下。

3.中断模块配置

4.RCC及SYS配置

5.LWIP模块配置

最后,别忘记使能LWIP模块,完成对其配置,打开第三方插件Middleware,勾选LWIP,里面可以看到LWIP使用的版本号,并完成LWIP的地址、掩码、TCP、BUF等参数的设置,如下所示。

下图中key Options参数在生成的lwipopts.h文件上可以看到。

提一句,CubeMX这里面用的LWIP跟外部官网上是一样,因为其开源免费的特性,CubeMX直接将其内嵌在软件里面使用。

在第三方插件Middleware界面上,还可以看到FATFS通用文件系统设置、以及freeRTOS线程设置等等,说明使用CubeMX可视化工具,很方便、功能也挺多。

3.生成代码

上面完成配置引脚、设置系统时钟、以及外设参数设置后,点击GENERATE CODE直接生成代码和工程文件,在保存的路径上面查看。

  

打开工程,查看代码如下。

1.main文件

这里将完成相关GPIO引脚、LWIP、定时器初始化配置,首先重置所有外围设备,初始化Flash接口和Systick,配置系统时钟,初始化所有已配置的外围设备;然后初始化用户UDP网络设置、和用户参数,并启动1毫秒定时器;最后进入主循环,处理网络上的数据,主要为MX_LWIP_Process()函数和UDP_Data_Process()函数完成,其中MX_LWIP_Process函数为CubeMX工具生成的函数,主要作用为处理网络上接收到的数据,传递给注册的接收回调函数UDP_Receive_Callback解析处理。代码示例如下。

/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2025 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under Ultimate Liberty license* SLA0044, the "License"; You may not use this file except in compliance with* the License. You may obtain a copy of the License at:*                             www.st.com/SLA0044********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "lwip.h"
#include "tim.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
#include "eth_user.h"
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/*** @brief  The application entry point.* @retval int*/
int main(void)
{/* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* Configure the system clock */SystemClock_Config();/* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM6_Init();MX_LWIP_Init();MX_TIM7_Init();User_UDP_Init();HAL_TIM_Base_Start_IT(&htim6); // 启动1ms定时器/* Infinite loop */while (1){Delay_us(100);MX_LWIP_Process();UDP_Data_Process();}
}
/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 8;RCC_OscInitStruct.PLL.PLLN = 320;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 4;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK){Error_Handler();}HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLLCLK, RCC_MCODIV_4);
}

2.用户层源文件

这里将完成网络用户层设置,主要为网络IP初始化设置、以及网络收发数控制,代码示例如下。

#include "eth_user.h"
#include "stm32f4xx_hal.h"
#include "lwip.h"
#include "lwip/igmp.h"#define UDP_PORT     8888 		  // 网络端口
static struct udp_pcb *upcb;    // UDP通讯的控制块对象
static DeviceStatus SendUDPSt;	// UDP通道的通讯状态
UDP_Message RecvUDPMes;
UDP_Message AckUDPMes;
UDP_Message SendUDPMes;
/******************************************************************************* 描述  : 初始化UDP所用的相关数据对象* 参数  : 无* 返回  : 无
******************************************************************************/
void UDP_Data_Init(void)
{memset(&RecvUDPMes, 0, sizeof(UDP_Message));memset(&AckUDPMes, 0, sizeof(UDP_Message));memset(&SendUDPMes, 0, sizeof(UDP_Message));memset(&SendUDPSt, 0, sizeof(DeviceStatus));SendUDPSt.ID = 0x10;
}
/******************************************************************************* 描述  : 接收回调函数编写* 参数  : upcb UDP协议控制块*         p 收到的数据包缓冲区*         addr 接收数据包的远程IP地址 *         port 接收数据包的远程端口* 返回  : 无
******************************************************************************/
static void UDP_Receive_Callback(void *arg, struct udp_pcb *upcb,struct pbuf *p, const ip_addr_t *addr, u16_t port)
{uint8_t udprecvbuf[MAX_UDP_FRAME_LEN] = {0};struct pbuf *ptmp = p;uint32_t data_len = 0;if(upcb != NULL && p != NULL){ip_addr_t remote_source_ip;IP4_ADDR(&remote_source_ip, 192,168,1,113);		if((port == UDP_PORT) && ((addr->addr) == remote_source_ip.addr)) //判断地址和端口从哪里来的{for (ptmp = p; ptmp != NULL; ptmp = ptmp->next)	 //遍历完整个buf链表{				//判断要拷贝到buf中的数据是否大于UDP_DEMO_RX_BUFSIZE的剩余空间,//如果大于的话就只拷贝剩余长度的数据,否则的话就拷贝所有的数据if (ptmp->len <= (MAX_UDP_FRAME_LEN - data_len)){					memcpy(udprecvbuf + data_len, ptmp->payload, ptmp->len);data_len += ptmp->len;}else{					memcpy(udprecvbuf + data_len, ptmp->payload, (MAX_UDP_FRAME_LEN - data_len)); //拷贝数据data_len = MAX_UDP_FRAME_LEN;}//超出UDP最大数据包,则跳出循环if (data_len > MAX_UDP_FRAME_LEN){				break; }}// 初步处理memcpy(&AckUDPMes, udprecvbuf, data_len);SendUDPSt.LastRecvTime = g_1msTick;SendUDPSt.ComSt = COM_ST_PENDING;if(*((uint32_t*)udprecvbuf) != UDP_FRAME_HEAD) { // 同步头校验AckUDPMes.AnsResult = ACK_HEAD_ERROR;}else if(AckUDPMes.Len != (data_len-4)) { // 帧长度校验AckUDPMes.AnsResult = ACK_LEN_ERROR;}else if(RecvUDPMes.CRC16 != CRC16_Calculate((uint8_t*)&RecvUDPMes.SN, RecvUDPMes.Len-4)) { // CRC校验AckUDPMes.AnsResult = ACK_CRC_ERROR;}else SendUDPSt.ComSt = COM_ST_INIT;}}pbuf_free(p); // 释放内存
}/******************************************************************************* 描述  : 创建udp客户端* 参数  : 无* 返回  : 无
******************************************************************************/
void User_UDP_Init(void)
{ip_addr_t local_ip;ip_addr_t remote_ip;err_t err;/* 初始化UDP数据消息 */UDP_Data_Init();// 组播配置//IP4_ADDR(&local_ip, 224,1,1,201);   //配置本地接收组播的地址//IP4_ADDR(&remote_ip, 224,1,1,113);//独播IP4_ADDR(&local_ip, 192,168,1,201);IP4_ADDR(&remote_ip, 192,168,1,113);upcb = udp_new();  // 创建udp控制块if (upcb!=NULL){	upcb->local_port = UDP_PORT;           // 配置本地端口upcb->local_ip.addr = local_ip.addr;   // 配置本地地址upcb->remote_port = UDP_PORT;          // 绑定远程端口upcb->remote_ip.addr = remote_ip.addr; // 绑定远程地址//加入组播//err= igmp_joingroup(IP_ADDR_ANY,&local_ip); //只需要将接收地址放入igmp组,发送的不需要//连接远程服务器IP和端口err= udp_connect(upcb, &remote_ip, UDP_PORT);if(err == ERR_OK){err = udp_bind(upcb,&local_ip,UDP_PORT); //只能收到绑定的本地接收ip地址和端口的数据//err = udp_bind(upcb,IP_ADDR_ANY,UDP_LOCAL_PORT); //可以收到固定端口上任意ip地址的数// 注册接收回调函数,只要接收到数据,这个回调函数会被lwip内核调用udp_recv(upcb, UDP_Receive_Callback, NULL);  // 函数初始化时注册-接收回调函数	}else{//离开组播地址//igmp_leavegroup(IP_ADDR_ANY,&local_ip);// 断开UDP连接udp_remove(upcb);}}
}/******************************************************************************* 描述  : 发送数据* 参数  : (in)pData 发送数据的指针* 返回  : 无
******************************************************************************/
int8_t UDP_Send_Data(struct udp_pcb *upcb, uint8_t *pData, uint16_t len)
{struct pbuf *p;int8_t ret = ERR_BUF;if (upcb != NULL && pData != NULL && len > 0){/* 分配缓冲区空间 */p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_POOL);if(p != NULL){/* 填充缓冲区数据 */ret = pbuf_take(p, pData, len);if(ret == ERR_OK){/* 发送udp数据 */ret = udp_send(upcb, p);}			/* 释放缓冲区空间 */pbuf_free(p);}}return ret;
}// 处理单项控制命令
CMD_Ack UDP_Single_Ctrl(UDP_Message msg)
{CMD_Ack ret = ACK_OK;if((uint8_t*)&msg != NULL){switch(msg.Param2){case 0:break;case 1:break;case 2:break;default:break;}}else{ret = ACK_ERROR;}return ret;	
}/******************************************************************************* 描述  : 将接收到的UDP数据包解析处理* 参数  : 无* 返回  : 无
******************************************************************************/
void UDP_Msgs_Process(void)
{if(SendUDPSt.ComSt == COM_ST_INIT) {AckUDPMes.AnsResult = UDP_Single_Ctrl(RecvUDPMes);SendUDPSt.ComSt = COM_ST_TRANS;}
}/******************************************************************************
* 描述  : 向以太网上发送UDP数据包* 参数  : 无* 返回  : 无
******************************************************************************/
void UDP_Send_Msgs(void)
{static uint32_t lastime = 0;/* deal ack data */if(SendUDPSt.ComSt != COM_ST_STOP) {AckUDPMes.Head = UDP_FRAME_HEAD;AckUDPMes.Len = UDP_MSG_LEN;AckUDPMes.CRC16 = CRC16_Calculate((uint8_t*)&AckUDPMes.SN, AckUDPMes.Len-4);UDP_Send_Data(upcb, (uint8_t*)&AckUDPMes, UDP_FULL_FRAM_LEN(AckUDPMes.Len));SendUDPSt.ComSt = COM_ST_STOP;memset(&AckUDPMes, 0, sizeof(UDP_Message));}/*d eal heartbeat data */if(g_1msTick - lastime > 1000) {lastime = g_1msTick;SendUDPMes.Head = UDP_FRAME_HEAD;SendUDPMes.Len = UDP_MSG_LEN + 2;SendUDPMes.SN += 1;SendUDPMes.Param1 = SUB_CMD_KEEPALIVE;SendUDPMes.Param2 = RUN_IDLE;SendUDPMes.AnsResult = ACK_PENDING;SendUDPMes.Data[0] = 0xff;SendUDPMes.Data[1] = 0xff;SendUDPMes.CRC16 = CRC16_Calculate((uint8_t*)&SendUDPMes.SN, SendUDPMes.Len-4);UDP_Send_Data(upcb, (uint8_t*)&SendUDPMes, UDP_FULL_FRAM_LEN(SendUDPMes.Len));}
}/******************************************************************************* 描述  : UDP处理流程(处理现有消息,调度发送队列)* 参数  : 无* 返回  : 无
******************************************************************************/
void UDP_Data_Process(void)
{UDP_Msgs_Process();UDP_Send_Msgs();
}

3.用户层头文件

#ifndef __UDP_USER_H
#define __UDP_USER_H#ifdef __cplusplusextern "C" {
#endif#include "stdint.h"
#include "string.h"
#include "crc.h"
#include "udp.h"
#include "timer.h"
#define MAX_UDP_BUF_SIZE 1000
typedef struct 
{uint32_t Head;      // 同步头uint16_t Len;       // 整帧长度(UDP_MSG_LEN+Data长度)uint16_t CRC16;     // CRC校验结果(UDP_MSG_LEN-4+Data长度的数据)uint16_t SN;        // 帧序号uint32_t Param1;    // 参数1uint32_t Param2;    // 参数2uint32_t AnsResult; // 应答结果uint8_t Data[MAX_UDP_BUF_SIZE]; // 数据内容(不能超过1024字节)
}__attribute__((packed)) UDP_Message;#define UDP_FRAME_HEAD 0xC3A53C5A				// 帧头
#define UDP_MSG_LEN 22				          // 帧头长度
#define UDP_FULL_FRAM_LEN(msgLen) ((msgLen)+4)	// 帧头+整帧长度
#define MAX_UDP_FRAME_LEN (4+UDP_MSG_LEN+MAX_UDP_BUF_SIZE)//sizeof(UDP_Message) UDP最大帧长度typedef enum
{ACK_PENDING = 0,        // 等待反馈ACK_OK = 0x10,          // 命令执行结束,且结果正常ACK_ERROR = 0x11,       // 命令执行过程发生异常ACK_WARNING = 0x12,     // 命令执行结束,但结果异常ACK_HEAD_ERROR = 0x20,   // Head校验错误ACK_CRC_ERROR  = 0x21,   // CRC校验错误ACK_LEN_ERROR  = 0x22,   // 长度校验错误ACK_CMD_INVALID = 0x23,  // 命令参数错误,无法执行ACK_RUNNING = 0x22,     // 有其他命令正在执行
}CMD_Ack; // 回应类型}Sub_CMD_Type;typedef enum
{RUN_IDLE 		  = 0x01,			// 空闲RUN_TEST_CTRL	= 0x02,			// 测试RUN_BURN_IN	  = 0x03,		  // 老炼RUN_UPGRADE		= 0x04			// 在线升级
}RunningStType;   // 软件运行状态类型typedef enum
{COM_ST_UNKNOWN 	= 0x00,		// 未知COM_ST_PENDING 	= 0x01,		// 等待回应COM_ST_INIT 	  = 0x02,		// 初步OKCOM_ST_TRANS 	  = 0x03,		// 可传输COM_ST_STOP	 	  = 0x04		// 已停止
}DeviceComStatus; // 设备通讯状态标识void User_UDP_Init(void);
int8_t UDP_Send_Data(struct udp_pcb *upcb, uint8_t *pData, uint16_t len);
void UDP_Msgs_Process(void);
void UDP_Send_Msgs(void);
void UDP_Data_Process(void);
#ifdef __cplusplus
}
#endif#endif

4.效果演示

编写完用户代码后,进行编译运行,连接仿真器在线调式、或者直接烧写到板子中,打开网络监控助手,效果如下。


总结

下面提供的代码,基于STM32F407ZGT芯片编写,可直接在原子开发板上运行,也可运行在各工程项目上,但需要注意各接口以及相应的引脚应和原子开发板上保持一致。

相应的代码链接:单片机STM32F407-Case程序代码例程-CSDN文库

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

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

相关文章

【Unity-Game4Automation PRO 插件】

Game4Automation PRO 插件 是一个用于 Unity 引擎 的工业自动化仿真工具&#xff0c;它提供了对工业自动化领域的仿真和虚拟调试支持&#xff0c;特别是在与工业机器人、生产线、PLC 系统的集成方面。该插件旨在将工业自动化的实时仿真与游戏开发的高质量 3D 可视化能力结合起来…

【安卓开发】【Android】总结:安卓技能树

【持续更新】 对笔者在安卓开发的实践中认为必要的知识点和遇到的问题进行总结。 一、基础知识部分 1、Android Studio软件使用 软件界面 最新的版本是瓢虫&#xff08;Ladybug&#xff09;&#xff0c;bug的确挺多。笔者更习惯使用电鳗&#xff08;Electric Eel&#xff0…

鸿蒙打包发布

HarmonyOS应用/元服务发布&#xff08;打包发布&#xff09; https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/ide-publish-app-V13?catalogVersionV13 密钥&#xff1a;包含非对称加密中使用的公钥和私钥&#xff0c;存储在密钥库文件中&#xff0c;格式…

Spring Boot 下的Swagger 3.0 与 Swagger 2.0 的详细对比

先说结论&#xff1a; Swgger 3.0 与Swagger 2.0 区别很大&#xff0c;Swagger3.0用了最新的注释实现更强大的功能&#xff0c;同时使得代码更优雅。 就个人而言&#xff0c;如果新项目推荐使用Swgger 3.0&#xff0c;对于工具而言新的一定比旧的好&#xff1b;对接于旧项目原…

SAP 固定资产常用的数据表有哪些,他们是怎么记录数据的?

在SAP系统中&#xff0c;固定资产管理&#xff08;FI-AA&#xff09;涉及多个核心数据表&#xff0c;用于记录资产主数据、折旧、交易等。以下是常用的数据表及其记录数据的逻辑&#xff1a; 1. ANKT - 资产主数据表 功能&#xff1a;存储资产主数据的文本描述。 字段&#x…

光伏储能电解水制氢仿真模型Matlab/Simulink

今天更新的内容为光伏储能制氢技术&#xff0c;这个方向我之前在21年就系统研究并发表过相关文章&#xff0c;经过这几年的发展&#xff0c;绿色制氢技术也受到更多高校的注意&#xff0c;本篇博客也是在原先文章的基础上进行更新。 首先让大家熟悉一下绿氢制取技术这个概念&a…

Redis 3.2.1在Win10系统上的安装教程

诸神缄默不语-个人CSDN博文目录 这个文件可以跟我要&#xff0c;也可以从官网下载&#xff1a;https://github.com/MicrosoftArchive/redis/releases 这个是微软以前维护的Windows版Redis安装包&#xff0c;如果想要比较新的版本可以从别人维护的项目里下&#xff08;https://…

基于springboot+vue.js+uniapp技术开发的一套大型企业MES生产管理系统源码,支持多端管理

企业级智能制造MES系统源码&#xff0c;技术架构&#xff1a;springboot vue-element-plus-admin 企业级云MES全套源码&#xff0c;支持app、小程序、H5、台后管理端 MES指的是制造企业生产过程执行系统&#xff0c;是一套面向制造企业车间执行层的生产信息化管理系统。MES系…

frameworks 之 AMS与ActivityThread交互

frameworks 之 AMS与ActivityThread交互 1. 类关系2. 流程2.1 AMS流程2.1 ActivityThread流程 3. 堆栈 讲解AMS 如何和 ActivityThread 生命周期调用流程 涉及到的类如下 frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.javaframeworks/base/cor…

Jmeter 简单使用、生成测试报告(一)

一、下载Jmter 去官网下载&#xff0c;我下载的是apache-jmeter-5.6.3.zip&#xff0c;解压后就能用。 二、安装java环境 JMeter是基于Java开发的&#xff0c;运行JMeter需要Java环境。 1.下载JDK、安装Jdk 2.配置java环境变量 3.验证安装是否成功&#xff08;java -versio…

网络编程 - - TCP套接字通信及编程实现

概述 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的传输层协议。在网络编程中&#xff0c;TCP常用于实现客户端和服务器之间的可靠数据传输。本文将基于C语言实现TCP服务端和客户端建立通信的过程。 三次握手 在…

2023-2024 学年 广东省职业院校技能大赛(高职组)“信息安全管理与评估”赛题一

2023-2024 学年 广东省职业院校技能大赛(高职组“信息安全管理与评估”赛题一&#xff09; 模块一:网络平台搭建与设备安全防护第一阶段任务书任务 1&#xff1a;网络平台搭建任务 2&#xff1a;网络安全设备配置与防护DCRS:DCFW:DCWS:DCBC:WAF: 模块二&#xff1a;网络安全事件…

thinkphp6 + redis实现大数据导出excel超时或内存溢出问题解决方案

redis下载安装&#xff08;window版本&#xff09; 参考地址&#xff1a;https://blog.csdn.net/Ci1693840306/article/details/144214215 php安装redis扩展 参考链接&#xff1a;https://blog.csdn.net/jianchenn/article/details/106144313 解决思路&#xff1a;&#xff0…

PT8M2302 触控 A/D 型 8-Bit MCU

1. 产品概述 PT8M2302 是一款可多次编程&#xff08; MTP &#xff09; A/D 型 8 位 MCU &#xff0c;其包括 2K*16bit MTP ROM 、 256*8bit SRAM、 ADC 、 PWM 、 Touch 等功能&#xff0c;具有高性能精简指令集、低工作电压、低功耗特性且完全集 成触控按键功能。为…

Nvidia Blackwell架构深度剖析:深入了解RTX 50系列GPU的升级

在CES 2025上&#xff0c;英伟达推出了基于Blackwell架构的GeForce RTX 50系列显卡&#xff0c;包括RTX 5090、RTX 5080、RTX 5070 Ti和RTX 5070。一段时间以来&#xff0c;我们已经知晓了该架构的各种细节&#xff0c;其中许多此前还只是传闻。不过&#xff0c;英伟达近日在20…

计算机网络 (45)动态主机配置协议DHCP

前言 计算机网络中的动态主机配置协议&#xff08;DHCP&#xff0c;Dynamic Host Configuration Protocol&#xff09;是一种网络管理协议&#xff0c;主要用于自动分配IP地址和其他网络配置参数给连接到网络的设备。 一、基本概念 定义&#xff1a;DHCP是一种网络协议&#xf…

RV1126+FFMPEG推流项目(7)AI音频模块编码流程

一、AI 模块和外设麦克风的关系 AI 模块是 RV1126 芯片的一个重要组成部分。它的主要功能是将外部接入的麦克风采集到的模拟信号通过内置的驱动程序转换为数字信号。这意味着麦克风作为外设&#xff0c;提供音频输入信号&#xff0c;AI 模块通过其硬件和软件的结合&#xff0c…

第十二章:算法与程序设计

文章目录&#xff1a; 一&#xff1a;基本概念 1.算法与程序 1.1 算法 1.2 程序 2.编译预处理 3.面向对象技术 4.程序设计方法 5.SOP标志作业流程 6.工具 6.1 自然语言 6.2 流程图 6.3 N/S图 6.4 伪代码 6.5 计算机语言 二&#xff1a;程序设计 基础 1.常数 …

【k8s面试题2025】2、练气初期

在练气初期&#xff0c;灵气还比较稀薄&#xff0c;只能勉强在体内运转几个周天。 文章目录 简述k8s静态pod为 Kubernetes 集群移除新节点&#xff1a;为 K8s 集群添加新节点Kubernetes 中 Pod 的调度流程 简述k8s静态pod 定义 静态Pod是一种特殊类型的Pod&#xff0c;它是由ku…

初学stm32 --- CAN

目录 CAN介绍 CAN总线拓扑图 CAN总线特点 CAN应用场景 CAN物理层 CAN收发器芯片介绍 CAN协议层 数据帧介绍 CAN位时序介绍 数据同步过程 硬件同步 再同步 CAN总线仲裁 STM32 CAN控制器介绍 CAN控制器模式 CAN控制器模式 CAN控制器框图 发送处理 接收处理 接收过…