当前位置: 首页 > 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; 输…...

颈腰椎病引发 “耳后疼痛”:耳根刺痛,可能是颈椎在 “捣乱”

很多人出现耳后持续性刺痛或按压痛&#xff0c;会误以为是中耳炎、腮腺炎&#xff0c;实则部分耳后疼痛与颈椎病变相关。颈椎病变压迫枕大神经&#xff08;从颈椎延伸至耳后&#xff09;&#xff0c;会导致神经分布区域疼痛&#xff1b;同时颈椎肌肉痉挛、僵硬&#xff0c;牵拉…...

【Mojo+Python混合部署失效真相】:92%开发者忽略的编译期符号冲突、运行时上下文隔离与调试断点丢失问题

第一章&#xff1a;MojoPython混合部署失效真相全景概览Mojo 作为新兴的高性能系统编程语言&#xff0c;设计初衷是与 Python 生态无缝互操作&#xff1b;然而在真实生产部署中&#xff0c;“Mojo Python 混合部署”常出现静默失败、ABI 不兼容、运行时崩溃或性能断崖式下降等…...

分支限界法 vs 回溯法:5个关键区别和实际应用场景对比

分支限界法与回溯法&#xff1a;核心差异与工程实践指南 在解决复杂组合优化问题时&#xff0c;算法选择往往决定了程序的执行效率。当面对NP难问题时&#xff0c;两种经典算法——分支限界法和回溯法——常被开发者拿来比较。本文将深入剖析这两种算法的本质区别&#xff0c;并…...

Django 学习日记(补充1)| 彻底吃透:自定义 JWT 认证 + 全局登录中间件

大家好&#xff0c;这是我 Django 学习日记的第三篇。上一篇我们把路由、反向解析、DRF 自动路由、媒体文件、跨域全部讲明白了。今天我们进入整个项目最核心、最安全、最关键的部分&#xff1a;用户登录认证体系&#xff08;在进入视图前的一篇补充文章&#xff09;。本文将从…...

Python实战:5分钟搞定Paillier同态加密的安装与基础使用(附避坑指南)

Python实战&#xff1a;5分钟搞定Paillier同态加密的安装与基础使用&#xff08;附避坑指南&#xff09; 隐私计算领域近年来发展迅猛&#xff0c;而同态加密作为其核心技术之一&#xff0c;正在金融、医疗等行业的数据协作场景中发挥越来越重要的作用。Paillier算法作为支持加…...

Llama-3.2V-11B-cot部署教程:bf16+auto device_map双卡4090显存优化详解

Llama-3.2V-11B-cot部署教程&#xff1a;bf16auto device_map双卡4090显存优化详解 1. 项目概述 Llama-3.2V-11B-cot是基于Meta Llama-3.2V-11B-cot多模态大模型开发的高性能视觉推理工具&#xff0c;专为双卡4090环境深度优化。本教程将详细介绍如何快速部署这一专业级解决方…...

Citra 3DS模拟器:如何在PC端重温任天堂经典游戏的终极指南

Citra 3DS模拟器&#xff1a;如何在PC端重温任天堂经典游戏的终极指南 【免费下载链接】citra A Nintendo 3DS Emulator 项目地址: https://gitcode.com/gh_mirrors/cit/citra 想要在Windows、Linux或macOS系统上体验《精灵宝可梦》、《塞尔达传说》等经典3DS独占游戏吗…...

物理海洋学入门:从海浪到海流,一文搞懂海水运动的7种形式

物理海洋学入门&#xff1a;从海浪到海流&#xff0c;一文搞懂海水运动的7种形式 海洋覆盖了地球71%的表面积&#xff0c;这片蔚蓝的水域从未停止过运动。当我们站在海边&#xff0c;看着潮起潮落、浪花拍岸&#xff0c;或许会好奇&#xff1a;这些看似简单的海水运动背后&…...

半导体晶圆测量中的5大常见误区:从台阶仪到无图晶圆系统的避坑指南

半导体晶圆测量中的5大常见误区&#xff1a;从台阶仪到无图晶圆系统的避坑指南 在半导体制造领域&#xff0c;晶圆测量是确保器件性能与良率的关键环节。然而&#xff0c;即使是经验丰富的工程师&#xff0c;也常因忽视某些细节而陷入测量陷阱。本文将揭示五个最具隐蔽性的操作…...

遥感影像配准总对不齐?OpenCV+RST+PROJ4三重坐标系对齐实战(附WGS84→UTM→影像本地坐标的转换矩阵速查表)

第一章&#xff1a;Shell脚本的基本语法和命令Shell脚本是Linux/Unix系统自动化任务的核心工具&#xff0c;以可执行文本文件形式存在&#xff0c;由Bash等shell解释器逐行解析运行。其语法简洁但严谨&#xff0c;对空格、分号、引号和换行符敏感&#xff0c;需严格遵循语法规则…...