当前位置: 首页 > news >正文

STM32上模拟CH340芯片的功能 (一)

#虚拟串口模拟CH340#

代码gitee地址:STM32F103_CH340: 用STM32模拟ch340USB串口的功能

一、思路

1. 确定通信接口:CH340是一款USB转串口芯片,因此您需要选择STM32上的某个USB接口来实现USB通信。通常情况下,STM32系列芯片都有内置的USB接口,您可以根据您的具体型号选择合适的接口。

2. 实现USB功能:在STM32上启用USB功能,您需要在代码中初始化USB接口,并配置相关的参数,例如USB模式、中断等。您可以参考STM32官方提供的库函数和示例代码来实现USB功能。

3. 实现串口功能:虚拟串口的核心功能是数据的收发,您需要实现串口的初始化、配置和中断处理等。在STM32上,UART或USART模块通常用于串口通信。您可以根据需求选择合适的串口模块,并在代码中进行相应的配置。

4. 实现CH340协议:CH340芯片有自己的通信协议,您需要在STM32上实现类似的协议。根据CH340的功能,您需要处理一些特定命令和数据格式,例如设置波特率、读写寄存器等。您可以在代码中定义相应的结构体和函数来处理CH340协议。

5. 编写数据收发逻辑:虚拟串口的关键是数据的收发,您需要编写代码来处理上位机发送的数据和发送数据给上位机。在接收数据时,您需要处理数据的帧格式和校验等,确保数据的完整性和正确性。在发送数据时,您需要按照CH340协议的要求组织数据并发送给上位机。

6. 测试与调试:完成代码编写后,您需要进行测试与调试,确保虚拟串口功能正常工作。您可以使用串口调试助手等工具来与虚拟串口进行通信并进行功能验证。

二、关键代码

1.CH340设备信息代码  

/********************************************************************************* @file    usb_desc.c* @brief   Descriptors for Virtual Com Port Demo******************************************************************************* @attention** <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>** Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");* You may not use this file except in compliance with the License.* You may obtain a copy of the License at:**        http://www.st.com/software_license_agreement_liberty_v2** Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.********************************************************************************//* 包含文件 ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_desc.h"/* USB 标准设备描述符 */
const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
{0x12,                             /* bLength */USB_DEVICE_DESCRIPTOR_TYPE,       /* bDescriptorType */0x10,0x01,                             /* bcdUSB = 1.10 */0xff,                             /* bDeviceClass: CDC */0x00,                             /* bDeviceSubClass */0x00,                             /* bDeviceProtocol */0x40,                             /* bMaxPacketSize0 */0x86,0x1a,                             /* idVendor = 0x1A86 */0x23,0x75,                             /* idProduct = 0x7523 */0x64,0x02,                             /* bcdDevice = 2.00 */1,                                /* 制造商描述符的索引 */2,                                /* 产品描述符的索引 */3,                                /* 设备序列号的描述符的索引 */0x01                              /* 配置描述符的数量 */
};const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
{/* 配置描述符 */0x09,                             /* bLength: 配置描述符的长度 */USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */VIRTUAL_COM_PORT_SIZ_CONFIG_DESC,  /* wTotalLength: 所有返回的字节数 */0x00,0x01,                             /* bNumInterfaces: 接口的数量 */0x01,                             /* bConfigurationValue: 配置值 */0x00,                             /* iConfiguration: 描述该配置的字符串描述符的索引 */0x80,                             /* bmAttributes: 自供电 */0x30,                             /* MaxPower: 0 mA *//* 接口描述符 */0x09,                             /* bLength: 接口描述符的长度 */USB_INTERFACE_DESCRIPTOR_TYPE,    /* bDescriptorType: Interface *//* 接口描述符类型 */0x00,                             /* bInterfaceNumber: 接口的编号 */0x00,                             /* bAlternateSetting: 替代设置 */0x03,                             /* bNumEndpoints: 使用的端点数 */0xff,                             /* bInterfaceClass: 通信接口类 */0x01,                             /* bInterfaceSubClass: 抽象控制模型 */0x02,                             /* bInterfaceProtocol: 通用 AT 命令 */0x00,                             /* iInterface: 描述该接口的字符串描述符的索引 *//* 端点2输入描述符 */0x07,                             /* bLength: 端点描述符的长度 */USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */0x82,                             /* bEndpointAddress: (IN2) */0x02,                             /* bmAttributes: 传输类型为批量传输 */0x20,                             /* wMaxPacketSize: 最大数据包大小 */0x00,0x00,                             /* bInterval: 传输间隔 *//* 端点2输出描述符 */0x07,                             /* bLength: 端点描述符的长度 */USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */0x02,                             /* bEndpointAddress: (OUT2) */0x02,                             /* bmAttributes: 传输类型为批量传输 */0x20,                             /* wMaxPacketSize: 最大数据包大小 */0x00,0x00,                             /* bInterval: 传输间隔 *//* 端点1输入描述符 */0x07,                             /* bLength: 端点描述符的长度 */USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */0x81,                             /* bEndpointAddress: (IN1) */0x03,                             /* bmAttributes: 传输类型为中断传输 */0x08,                             /* wMaxPacketSize: 最大数据包大小 */0x00,0x01                              /* bInterval: 传输间隔 */
};/* USB 字符串描述符 */
const uint8_t Virtual_Com_Port_StringLangID[VIRTUAL_COM_PORT_SIZ_STRING_LANGID] =
{VIRTUAL_COM_PORT_SIZ_STRING_LANGID,USB_STRING_DESCRIPTOR_TYPE,0x09,0x04 /* LangID = 0x0409: U.S. English */
};const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR] =
{VIRTUAL_COM_PORT_SIZ_STRING_VENDOR,  /* 制造商字符串的大小 */USB_STRING_DESCRIPTOR_TYPE,          /* bDescriptorType*//* 制造商名称: "wch.cn" */'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0
};const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT] =
{VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT,  /* bLength */USB_STRING_DESCRIPTOR_TYPE,           /* bDescriptorType *//* 产品名称: "USB 串口" */'U', 0, 'S', 0, 'B', 0, ' ', 0, 'S', 0, 'e', 0, 'r', 0, 'i', 0, 'a', 0, 'l', 0
};uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] =
{VIRTUAL_COM_PORT_SIZ_STRING_SERIAL,   /* bLength */USB_STRING_DESCRIPTOR_TYPE,           /* bDescriptorType *//* 设备序列号: "0123456789" */'0', 0, '1', 0, '2', 0, '3', 0, '4', 0, '5', 0 , '6', 0, '7', 0, '8', 0, '9', 0
};/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2.添加CH340特有初始化代码

- `Virtual_Com_Port_Init`函数:初始化虚拟串口设备,包括获取设备的唯一序列号、设置设备的配置和连接状态等。

- `Virtual_Com_Port_Reset`函数:重置虚拟串口设备,包括设置设备的初始状态和清零设备配置和接口信息。

- `Virtual_Com_Port_SetConfiguration`函数:根据设备的配置信息更新设备状态。

- `Virtual_Com_Port_SetDeviceAddress`函数:设置设备的地址。

- `Virtual_Com_Port_Status_In`和`Virtual_Com_Port_Status_Out`函数:处理设备的状态 IN 和 OUT 请求。

- `Virtual_Com_Port_Data_Setup`函数:处理数据类特定的请求,如获取和设置线编码等。

- `Virtual_Com_Port_NoData_Setup`函数:处理非数据类特定的请求,如设置串口控制线状态等。

- `Virtual_Com_Port_GetDeviceDescriptor`、`Virtual_Com_Port_GetConfigDescriptor`和`Virtual_Com_Port_GetStringDescriptor`函数:获取设备描述符、配置描述符和字符串描述符。

/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name          : usb_prop.c
* Author             : MCD Application Team
* Version            : V2.2.0
* Date               : 06/13/2008
* Description        : All processing related to Virtual Com Port Demo
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************//* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_conf.h"
#include "usb_prop.h"
#include "usb_desc.h"
#include "usb_pwr.h"
#include "hw_config.h"
u32 ch341_state=0xeeff;
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u8 Request = 0;
void USART_Config_Default(void)
{}LINE_CODING linecoding ={115200, /* baud rate*/0x00,   /* stop bits-1*/0x00,   /* parity - none*/0x08    /* no. of bits 8*/};/* -------------------------------------------------------------------------- */
/*  Structures initializations */
/* -------------------------------------------------------------------------- */DEVICE Device_Table ={EP_NUM,1};DEVICE_PROP Device_Property ={Virtual_Com_Port_init,Virtual_Com_Port_Reset,Virtual_Com_Port_Status_In,Virtual_Com_Port_Status_Out,Virtual_Com_Port_Data_Setup,Virtual_Com_Port_NoData_Setup,Virtual_Com_Port_Get_Interface_Setting,Virtual_Com_Port_GetDeviceDescriptor,Virtual_Com_Port_GetConfigDescriptor,Virtual_Com_Port_GetStringDescriptor,0,0x40 /*MAX PACKET SIZE*/};USER_STANDARD_REQUESTS User_Standard_Requests ={Virtual_Com_Port_GetConfiguration,Virtual_Com_Port_SetConfiguration,Virtual_Com_Port_GetInterface,Virtual_Com_Port_SetInterface,Virtual_Com_Port_GetStatus,Virtual_Com_Port_ClearFeature,Virtual_Com_Port_SetEndPointFeature,Virtual_Com_Port_SetDeviceFeature,Virtual_Com_Port_SetDeviceAddress};ONE_DESCRIPTOR Device_Descriptor ={(u8*)Virtual_Com_Port_DeviceDescriptor,VIRTUAL_COM_PORT_SIZ_DEVICE_DESC};ONE_DESCRIPTOR Config_Descriptor ={(u8*)Virtual_Com_Port_ConfigDescriptor,VIRTUAL_COM_PORT_SIZ_CONFIG_DESC};ONE_DESCRIPTOR String_Descriptor[4] ={{(u8*)Virtual_Com_Port_StringLangID, VIRTUAL_COM_PORT_SIZ_STRING_LANGID},{(u8*)Virtual_Com_Port_StringVendor, VIRTUAL_COM_PORT_SIZ_STRING_VENDOR},{(u8*)Virtual_Com_Port_StringProduct, VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT},{(u8*)Virtual_Com_Port_StringSerial, VIRTUAL_COM_PORT_SIZ_STRING_SERIAL}};/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Extern function prototypes ------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name  : Virtual_Com_Port_init.
* Description    : Virtual COM Port Mouse init routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Virtual_Com_Port_init(void)
{/* Update the serial number string descriptor with the data from the uniqueID*/Get_SerialNum();pInformation->Current_Configuration = 0;/* Connect the device */PowerOn();/* USB interrupts initialization *//* clear pending interrupts */_SetISTR(0);wInterrupt_Mask = IMR_MSK;/* set interrupts mask */_SetCNTR(wInterrupt_Mask);/* configure the USART 1 to the default settings */USART_Config_Default();bDeviceState = UNCONNECTED;
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_Reset
* Description    : Virtual_Com_Port Mouse reset routine
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Virtual_Com_Port_Reset(void)
{/* Set Virtual_Com_Port DEVICE as not configured */pInformation->Current_Configuration = 0;/* Current Feature initialization */pInformation->Current_Feature = Virtual_Com_Port_ConfigDescriptor[7];/* Set Virtual_Com_Port DEVICE with the default Interface*/pInformation->Current_Interface = 0;SetBTABLE(BTABLE_ADDRESS);/* Initialize Endpoint 0 */SetEPType(ENDP0, EP_CONTROL);SetEPTxStatus(ENDP0, EP_TX_STALL);SetEPRxAddr(ENDP0, ENDP0_RXADDR);SetEPTxAddr(ENDP0, ENDP0_TXADDR);Clear_Status_Out(ENDP0);SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);SetEPRxValid(ENDP0);/* Initialize Endpoint 1 */SetEPType(ENDP1, EP_INTERRUPT);SetEPTxAddr(ENDP1, ENDP1_TXADDR);SetEPTxStatus(ENDP1, EP_TX_NAK);SetEPRxStatus(ENDP1, EP_RX_DIS);// SetEPRxValid(ENDP1);/* Initialize Endpoint 2 */SetEPType(ENDP2, EP_BULK);SetEPTxAddr(ENDP2, ENDP2_TXADDR);SetEPTxStatus(ENDP2, EP_TX_NAK);SetEPRxStatus(ENDP2, EP_RX_VALID);// SetEPRxValid(ENDP2);/* Initialize Endpoint 2 */SetEPType(ENDP2, EP_BULK);SetEPRxAddr(ENDP2, ENDP2_RXADDR);SetEPRxCount(ENDP2, VIRTUAL_COM_PORT_DATA_SIZE);/* Set this device to response on default address */SetDeviceAddress(DADDR_EF|0);// SetDeviceAddress(0);bDeviceState = ATTACHED;
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_SetConfiguration.
* Description    : Udpade the device state to configured.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Virtual_Com_Port_SetConfiguration(void)
{DEVICE_INFO *pInfo = &Device_Info;if (pInfo->Current_Configuration != 0){/* Device configured */bDeviceState = CONFIGURED;}
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_SetConfiguration.
* Description    : Udpade the device state to addressed.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Virtual_Com_Port_SetDeviceAddress (void)
{bDeviceState = ADDRESSED;
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_Status_In.
* Description    : Virtual COM Port Status In Routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Virtual_Com_Port_Status_In(void)
{if (Request == SET_LINE_CODING){USART_Config();Request = 0;}
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_Status_Out
* Description    : Virtual COM Port Status OUT Routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Virtual_Com_Port_Status_Out(void)
{}/*******************************************************************************
* Function Name  : Virtual_Com_Port_Data_Setup
* Description    : handle the data class specific requests
* Input          : Request Nb.
* Output         : None.
* Return         : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
static u8 vender_request;u8 *Vender_Handle_CH341(u16 Length)
{u16 wValue = pInformation->USBwValues.w;u16 wIndex = pInformation->USBwIndexs.w;static u8 buf1[2]={0x30,0};static u8 buf2[2]={0xc3,0};change_byte(wValue);change_byte(wIndex);if (Length == 0 && (vender_request==0x5f||vender_request==0x95)){pInformation->Ctrl_Info.Usb_wLength=2;return 0;}switch(vender_request){case 0x5f:return buf1;case 0x95:if (wValue==0x2518){return buf2;}       else if(wValue==0x0706){return (u8 *)&ch341_state; }            }return 0;
}
RESULT Virtual_Com_Port_Data_Setup(u8 RequestNo)
{u8    *(*CopyRoutine)(u16);CopyRoutine = NULL;if (RequestNo == GET_LINE_CODING){if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)){CopyRoutine = Virtual_Com_Port_GetLineCoding;}}else if (RequestNo == SET_LINE_CODING){if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)){CopyRoutine = Virtual_Com_Port_SetLineCoding;}Request = SET_LINE_CODING;}else{vender_request=RequestNo;CopyRoutine = Vender_Handle_CH341; }if (CopyRoutine == NULL){return USB_UNSUPPORT;}pInformation->Ctrl_Info.CopyData = CopyRoutine;pInformation->Ctrl_Info.Usb_wOffset = 0;(*CopyRoutine)(0);return USB_SUCCESS;
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_NoData_Setup.
* Description    : handle the no data class specific requests.
* Input          : Request Nb.
* Output         : None.
* Return         : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/#define CH341_BAUDBASE_FACTOR 1532620800L
RESULT Virtual_Com_Port_NoData_Setup(u8 RequestNo)
{if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)){if (RequestNo == SET_COMM_FEATURE){return USB_SUCCESS;}else if (RequestNo == SET_CONTROL_LINE_STATE){return USB_SUCCESS;}}else//CH341 specific{u16 wValue = pInformation->USBwValues.w;u16 wIndex = pInformation->USBwIndexs.w;static u32 baud_factor;static u8 divisor;change_byte(wValue);change_byte(wIndex);switch(RequestNo){case 0XA1:break;case CH341_REQ_WRITE_REG:switch(wValue){case 0x1312:baud_factor&=0x00ff;baud_factor|=(wIndex&0xff00);divisor=wIndex&0x03;break; case 0x0f2c:baud_factor&=0xff00;baud_factor|=wIndex;        break;}  break; case 0xA4: ch341_state=0xee9f;break;}return USB_SUCCESS;           }return USB_UNSUPPORT;
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_GetDeviceDescriptor.
* Description    : Gets the device descriptor.
* Input          : Length.
* Output         : None.
* Return         : The address of the device descriptor.
*******************************************************************************/
u8 *Virtual_Com_Port_GetDeviceDescriptor(u16 Length)
{return Standard_GetDescriptorData(Length, &Device_Descriptor);
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_GetConfigDescriptor.
* Description    : get the configuration descriptor.
* Input          : Length.
* Output         : None.
* Return         : The address of the configuration descriptor.
*******************************************************************************/
u8 *Virtual_Com_Port_GetConfigDescriptor(u16 Length)
{return Standard_GetDescriptorData(Length, &Config_Descriptor);
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_GetStringDescriptor
* Description    : Gets the string descriptors according to the needed index
* Input          : Length.
* Output         : None.
* Return         : The address of the string descriptors.
*******************************************************************************/
u8 *Virtual_Com_Port_GetStringDescriptor(u16 Length)
{u8 wValue0 = pInformation->USBwValue0;if (wValue0 > 4){return NULL;}else{return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);}
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_Get_Interface_Setting.
* Description    : test the interface and the alternate setting according to the
*                  supported one.
* Input1         : u8: Interface : interface number.
* Input2         : u8: AlternateSetting : Alternate Setting number.
* Output         : None.
* Return         : The address of the string descriptors.
*******************************************************************************/
RESULT Virtual_Com_Port_Get_Interface_Setting(u8 Interface, u8 AlternateSetting)
{if (AlternateSetting > 0){return USB_UNSUPPORT;}else if (Interface > 1){return USB_UNSUPPORT;}return USB_SUCCESS;
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_GetLineCoding.
* Description    : send the linecoding structure to the PC host.
* Input          : Length.
* Output         : None.
* Return         : Inecoding structure base address.
*******************************************************************************/
u8 *Virtual_Com_Port_GetLineCoding(u16 Length)
{if (Length == 0){pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);return NULL;}return(u8 *)&linecoding;
}/*******************************************************************************
* Function Name  : Virtual_Com_Port_SetLineCoding.
* Description    : Set the linecoding structure fields.
* Input          : Length.
* Output         : None.
* Return         : Linecoding structure base address.
*******************************************************************************/
u8 *Virtual_Com_Port_SetLineCoding(u16 Length)
{if (Length == 0){pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);return NULL;}return(u8 *)&linecoding;
}

三、测试

1.下载程序后,USB连接

2.用串口自发自收测试

相关文章:

STM32上模拟CH340芯片的功能 (一)

#虚拟串口模拟CH340# 代码gitee地址&#xff1a;STM32F103_CH340: 用STM32模拟ch340USB串口的功能 一、思路 1. 确定通信接口&#xff1a;CH340是一款USB转串口芯片&#xff0c;因此您需要选择STM32上的某个USB接口来实现USB通信。通常情况下&#xff0c;STM32系列芯片都有内…...

图论——最小生成树

图论——最小生成树 A wise man changes his mind, a fool never will 生成树 一个连通图的生成树是一个极小的连通子图&#xff0c;它包含图中全部的n个顶点&#xff0c;但只有构成一棵树的n-1条边。 最小生成树 在这些边中选择N-1条出来&#xff0c;连接所有的N个点。这N-1…...

C++基础 -42- STL库之list链表

———————STL库之list链表——————— &#x1f384; list链表的格式(需要定义头文件) list<int> data1(4, 100);list<int> data2(4, 500);&#x1f384;list链表的合并接口 &#x1f384;举例使用合并接口并且验证 data2.merge(data1);list<int>::…...

Backend - Python 序列化

目录 一、作用1&#xff1a;代码块存入数据库 二、作用2&#xff1a;前后端传递数据 &#xff08;一&#xff09;前端 1. JSON.stringify() 2. JSON.parse() &#xff08;二&#xff09;后端 1. json.dumps() &#xff08;1&#xff09;作用 &#xff08;2&#xff09…...

初级数据结构(一)——顺序表

文中代码源文件已上传&#xff1a;数据结构源码 <-上一篇 NULL | 初级数据结构&#xff08;二&#xff09;——链表 下一篇-> 1、顺序表的特点 1.1、数组 现实中数据记录一般都记录在表格中&#xff0c;如进货单、菜单等&#xff0c;它们的最大特点就是…...

实现:切换页面切换标题,扩展 vue-router 的类型

布局容器-页面标题 网址&#xff1a;https://router.vuejs.org/zh/guide/advanced/meta 给每一个路由添加 元信息 数据 router/index.ts const router createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{ path: /login, component: () > im…...

已通过考试和认证注册以及后续计划表

已通过考试和认证注册以及后续计划表 软考 - 计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试信息系统集成及服务项目管理人员工程类考试计划你关注的证书样子 软考 - 计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试 高级 信息系统项目管理师&…...

开源计算机视觉库OpenCV详解

目录 1、概述 2、OpenCV详细介绍 2.1、OpenCV的起源 2.2、OpenCV开发语言 2.3、OpenCV的应用领域 3、OpenCV模块划分 4、OpenCV源码文件结构 4.1、根目录介绍 4.2、常用模块介绍 4.3、CUDA加速模块 5、OpenCV配置以及Visual Studio使用OpenCV 6、关于Lena图片 7、…...

使用pytorch查看中间层特征矩阵以及卷积核参数

这篇是我对哔哩哔哩up主 霹雳吧啦Wz 的视频的文字版学习笔记 感谢他对知识的分享 1和4是之前讲过的alexnet和resnet模型 2是分析中间层特征矩阵的脚本 3是查看卷积核参数的脚本 1设置预处理方法 和图像训练的时候用的预处理方法保持一致 2实例化模型 3载入之前的模型参数 4载入…...

HarmonyOS4.0从零开始的开发教程09页签切换

HarmonyOS&#xff08;七&#xff09;页签切换 List组件和Grid组件的使用 Tabs组件的使用 概述 在我们常用的应用中&#xff0c;经常会有视图内容切换的场景&#xff0c;来展示更加丰富的内容。比如下面这个页面&#xff0c;点击底部的页签的选项&#xff0c;可以实现“首页…...

大电流H桥电机驱动电路的设计与解析(包括自举电路的讲解,以IR2104+LR7843为例)

大电流H桥电机驱动电路的设计与解析&#xff08;包括自举电路的讲解&#xff0c;以IR2104LR7843为例&#xff09; 电机驱动板主要采用两种驱动芯片&#xff0c;一种是全桥驱动&#xff08;如&#xff1a;HIP4082&#xff09;&#xff0c;一种是半桥驱动&#xff08;如&#xff…...

windows11 windows 11 (win11 win 11) 怎么安装 Python3 ? numpy? sounddevice? 声音信号处理库?

首先确认要安装的 sounddevice 库&#xff0c;链接&#xff1a;https://python-sounddevice.readthedocs.io/en/0.4.6/ 根据文档&#xff0c;可知最新的 sounddevice 版本是 0.4.6 进入安装页面查看&#xff0c;发现 Newest sounddevice 可以使用 pip 安装&#xff0c;如下图…...

git如何配置多个远程仓库,并且进行切换

一、配置多个远程仓库并进行切换&#xff0c;请按照以下步骤进行操作&#xff1a; 打开命令行终端&#xff0c;并进入您的 Git 仓库所在的目录。添加第一个远程仓库&#xff0c;使用以下命令&#xff1a;git remote add origin <第一个远程仓库的 URL>这里将远程仓库命名…...

计算机存储单位 + 程序编译过程

C语言的编译过程 计算机存储单位 头文件包含的两种方式 使用 C/C 程序常用的IDE 常用的C语言编译器&#xff1a; 在选择编译器时&#xff0c;需考虑平台兼容性、性能优化、调试工具和开发人员的个人偏好等因素。 详细教程可转 爱编程的大丙...

vue路由导航守卫(全局守卫、路由独享守卫、组件内守卫)

目录 一、什么是Vue路由导航守卫&#xff1f; 二、全局守卫 1、beforeEach 下面是一个beforeEach的示例代码&#xff1a; 2、beforeResolve 下面是一个beforeResolve的示例代码&#xff1a; 3、afterEach 下面是一个afterEach的示例代码&#xff1a; 三、路由独享守卫…...

单片机双机通信控制跑马灯

实验要求 两个单片机各驱动8个LED灯&#xff0c;构成两个跑马灯&#xff0c;要求甲单片机LED的点亮方式是从上至下&#xff0c;首先是最上面第一个点亮、其次是前两个点亮、其次是前三个点亮……直至8个灯全部点亮&#xff0c;8个灯全部灭&#xff0c;重复这个过程&#xff0c…...

微信小程序:button微信开放能力打开客服会话分享到聊天框

文档 https://developers.weixin.qq.com/miniprogram/dev/component/button.html 打开客服会话 按钮关键属性 open-type"contact"功能按钮 <button class"mo-open-type"open-type"contact"> </button>分享 <button class&q…...

【数据结构】——队列实现二叉树的功能

前言&#xff1a;二叉树的实现方式多种多样&#xff0c;有数组实现满二叉树&#xff0c;有链表实现完全二叉树&#xff0c;今天我们就用队列来实现二叉树。 创建二叉树&#xff1a; typedef int BTDataType; typedef struct BinaryTreeNode {BTDataType data;struct BinaryTre…...

【已解决】Win7虚拟机安装VMtools报错

在做以前的实验的时候发现要用到Win7虚拟机&#xff0c;于是就安装了一个Win7的虚拟机&#xff0c;但是发现屏幕太小&#xff0c;而且来回复制文本、复制文件太不方便了&#xff0c;索性就安装了VMtools&#xff0c;发现还安装不成– 情况1 报错&#xff1a;本程序需要您将此…...

华为OD机试真题-小明找位置-2023年OD统一考试(C卷)

题目描述&#xff1a; 小朋友出操&#xff0c;按学号从小到大排成一列&#xff1b;小明来迟了&#xff0c;请你给小明出个主意&#xff0c;让他尽快找到他应该排的位置。 算法复杂度要求不高于nLog(n)&#xff1b;学号为整数类型&#xff0c;队列规模<10000&#xff1b; 输…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

ubuntu22.04有线网络无法连接,图标也没了

今天突然无法有线网络无法连接任何设备&#xff0c;并且图标都没了 错误案例 往上一顿搜索&#xff0c;试了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动&#xff0c;重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...