如遇开发技术问题,欢迎前往开发者社区,极海技术团队将在线为您解答~
极海官方开发者社区​https://community.geehy.cn/

《APM32芯得》系列内容为用户使用APM32系列产品的经验总结,均转载自21ic论坛极海半导体专区,全文未作任何修改,未经原文作者授权禁止转载。

目录

1、USB设备描述符

2、USB配置描述符

3、USB HID报告描述符

4、修改端点缓存地址


    最近在编写DMA_ADC例程的过程中出现了一个中断配置的问题,在ADC采集过程中,结合手册进行ADC连续转换模式配置采集,手册上给出需要进行中断配置的信息,但是真实情况不需要进行中断配置也可以进行ADC连续转换采集,因此,我没过滤掉ADC采集中开启中断配置的信息,开启了ADC中断采集,因此这次以APM32F411官方例程中的DMA_ADC例程,复刻了此次出现的问题。

APM32F103具有USB全速接口,可以做USB从机的多种功能。USB协议中为了提供对多样设备的支持,定义了许多外部设备子类,常见的包括:

  • 人机交互类设备HID(Human Interface Device)

  • 通信类设备CDC(Communicate Device Class)

  • 大容量存储设备MSC(Mass Storage Class)

  • 视频类设备UVC(USB Video Class)

  • 音频类设备UAC(USB Audio Class)

HID (Human Interface Device) 是一种用于连接人机交互设备的USB设备类别。它定义了一组通用的协议和规范,用于支持键盘、鼠标、游戏控制器等各种输入设备的连接和交互。

CDC(Communication Device Class)是USB组织定义的一类专门给各种通信设备(电信通信设备和中速网络通讯设备)使用的USB子类,常用于虚拟串口。

USB大容量存储设备类(The USB mass storage device class)是一种计算机和移动设备之间的传输协议,它允许一个通用串行总线(USB)设备来访问主机的计算设备,使两者之间进行文件传输,常用于存储器读写和模拟U盘。

SDK中提供的例程就有虚拟串口CDC、鼠标HID、模拟U盘MSC的功能。

除了这些USB做单项功能的,USB还可以配置复合设备,能同时集成了多个不同类型的外设,可以实现多个功能的同时使用

接下来就尝试在极海SDK中增加HID KeyBoard+CDC 虚拟串口的复合设备配置,修改就基于极海APM32F10x_SDK_V1.8中已有的USB_CDC_VirtualCOMPort例程,就不用重新配置虚拟串口部分了。

实现要对USB的描述符进行修改,能让电脑识别出来是个什么设备。

1、USB设备描述符

重点是bDeviceClass改成0xEF,告诉电脑这是个复合设备。

const uint8_t g_usbDeviceDescriptor[USB_DEVICE_DESCRIPTOR_SIZE] ={0x12,  /*bLength:长度,设备描述符的长度为18字节*/USBD_DESC_DEVICE, /*bDescriptorType*/0x00,0x02,                     /*bcdUSB = 2.00 */0xEF,                       /*bDeviceClass*/0x02,                       /*bDeviceSubClass*/0x01,                       /*bDeviceProtocol*/0x40,                       /*bMaxPacketSize40---------------------------*/0x83,0x05,                  /*idVendor (0x0583)*/0x50,0x57,                  /*idProduct = 0x5750*/0x00,                       /*bcdDevice rel. 2.00*/0x02,1,                          /*Index of string descriptor describingmanufacturer */2,                          /*Index of string descriptor describingproduct*/3,                          /*Index of string descriptor describing thedevice serial number */0x01                        /*bNumConfigurations*/};

2、USB配置描述符

这里配置USB的配置描述符、接口描述符和端点描述符。

HID键盘使用两个端点,端点4(IN)和端点4(OUT)

VCP虚拟串口使用三个端点,端点1(IN)、端点1(OUT)和端点2(IN)

const uint8_t g_usbConfigDescriptor[USB_CONFIG_DESCRIPTOR_SIZE] ={0x09, /* bLength: Configuration Descriptor size */USBD_DESC_CONFIGURATION, /* bDescriptorType: Configuration */USB_CONFIG_DESCRIPTOR_SIZE,/* wTotalLength: Bytes returned */0x00,0x03,         /* bNumInterfaces: 1 interface */0x01,         /* bConfigurationValue: Configuration value */0x00,         /* iConfiguration: Index of string descriptor describingthe configuration*/0xC0,         /* bmAttributes: Self powered */0x32,         /* MaxPower 100 mA: this current is used for detecting Vbus *//*************************************功能1 HID键盘**************************************//*IAD描述符*/0x08,   //bLength:IAD描述符大小 0x0B,   //bDescriptorType:IAD描述符类型0x00,   //bFirstInterface:功能1 HID键盘的第一个接口描述符是在总的配置描述符中的第几个从0开始数0x01,   //bInferfaceCount:功能1 HID键盘有1个接口描述符0x03,   //bFunctionClass:同单HID功能时,设备符中的bDeviceClass0x00,   //bFunctionSubClass:同单HID功能时,设备符中的bDeviceSubClass0x01,   //bFunctionProtocol:同单HID功能时,设备符中的bDeviceProtocol0x00,   //iFunction:字符串描述中关于此设备的索引(个人理解是一个字符串描述符中有比如0~5是功能1的字符串,//6~10是功能2的字符串,如果是功能2的话,此值为6)/************** Descriptor of Custom HID interface ****************//* 09 */0x09,         /* bLength: Interface Descriptor size */USBD_DESC_INTERFACE,/* bDescriptorType: Interface descriptor type */0x00,         /* bInterfaceNumber: Number of Interface */0x00,         /* bAlternateSetting: Alternate setting */0x02,         /* bNumEndpoints */0x03,         /* bInterfaceClass: HID */0x01,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */0x01,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */0,            /* iInterface: Index of string descriptor *//******************** Descriptor of Custom HID HID ********************//* 18 */0x09,         /* bLength: HID Descriptor size */0x21, /* bDescriptorType: HID */0x10,         /* bcdHID: HID Class Spec release number */0x01,0x00,         /* bCountryCode: Hardware target country */0x01,         /* bNumDescriptors: Number of HID class descriptors to follow */0x22,         /* bDescriptorType */KEYBOARD_SIZ_REPORT_DESC,//KEYBOARD_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */0x00,/******************** Descriptor of Custom HID endpoints ******************//* 27 */0x07,          /* bLength: Endpoint Descriptor size */USBD_DESC_ENDPOINT, /* bDescriptorType: */0x84,          /* bEndpointAddress: Endpoint Address (IN) */0x03,          /* bmAttributes: Interrupt endpoint */0x08,          /* wMaxPacketSize: 8 Bytes max */0x00,0x20,          /* bInterval: Polling Interval (32 ms) *//* 34 */        0x07,        /* bLength: Endpoint Descriptor size */USBD_DESC_ENDPOINT,        /* bDescriptorType: *//*        Endpoint descriptor type */0x04,        /* bEndpointAddress: *//*        Endpoint Address (OUT) */0x03,        /* bmAttributes: Interrupt endpoint */0x01,        /* wMaxPacketSize: 2 Bytes max  */0x00,0x20,        /* bInterval: Polling Interval (20 ms) *//* 41 *//********************************功能2 VCP虚拟串口*****************************//*IAD描述符*//* Interface Association Descriptor(IAD Descriptor)  */ 0x08,   /*  bLength  */0x0B,   /*  bDescriptorType*/0x01,   /*  bFirstInterface*/0x02,   /*  bInterfaceCount*/0x02,   /*  bFunctionClass --CDC*/0x02,   /*  bFunctionSubClass*/0x01,   /*  bFunctionProtocoll*/0x00,   /*  iFunction *//**VCP虚拟串口**//*Interface Descriptor接口描述符*/0x09,   /* bLength: Interface Descriptor size */USBD_DESC_INTERFACE,  /* bDescriptorType: Interface *//* Interface descriptor type */0x01,   /* bInterfaceNumber: Number of Interface */   //<接口 1>0x00,   /* bAlternateSetting: Alternate setting */0x01,   /* bNumEndpoints: One endpoints used 该接口非0端点数*/0x02,   /* bInterfaceClass: Communication Interface Class */0x02,   /* bInterfaceSubClass: Abstract Control Model */0x01,   /* bInterfaceProtocol: Common AT commands */0x00,   /* iInterface: *//*Header Functional Descriptor类描述符*/0x05,   /* bLength: Endpoint Descriptor size */0x24,   /* bDescriptorType: CS_INTERFACE */0x00,   /* bDescriptorSubtype: Header Func Desc */0x10,   /* bcdCDC: spec release number */0x01,/*Call Management Functional Descriptor*/0x05,   /* bFunctionLength */0x24,   /* bDescriptorType: CS_INTERFACE */0x01,   /* bDescriptorSubtype: Call Management Func Desc */0x00,   /* bmCapabilities: D0+D1 */0x01,   /* bDataInterface: 1 *//*ACM Functional Descriptor*/0x04,   /* bFunctionLength */0x24,   /* bDescriptorType: CS_INTERFACE */0x02,   /* bDescriptorSubtype: Abstract Control Management desc */0x02,   /* bmCapabilities *//*Union Functional Descriptor*/0x05,   /* bFunctionLength */0x24,   /* bDescriptorType: CS_INTERFACE */0x06,   /* bDescriptorSubtype: Union func desc */0x00,   /* bMasterInterface: Communication class interface */0x01,   /* bSlaveInterface0: Data Class Interface *//*Endpoint 2 Descriptor端点描述符*/0x07,   /* bLength: Endpoint Descriptor size */USBD_DESC_ENDPOINT,   /* bDescriptorType: Endpoint */0x82,   /* bEndpointAddress: (IN2) */0x03,   /* bmAttributes: Interrupt */VIRTUAL_COM_PORT_INT_SIZE,      /* wMaxPacketSize: */0x00,0xFF,   /* bInterval: *//*Data class interface descriptor类描述符*/0x09,   /* bLength: Endpoint Descriptor size */USBD_DESC_INTERFACE,  /* bDescriptorType: */0x02,   /* bInterfaceNumber: Number of Interface */0x00,   /* bAlternateSetting: Alternate setting */0x02,   /* bNumEndpoints: Two endpoints used */0x0A,   /* bInterfaceClass: CDC */0x00,   /* bInterfaceSubClass: */0x00,   /* bInterfaceProtocol: */0x00,   /* iInterface: *//*Endpoint 3 Descriptor端点描述符*/0x07,   /* bLength: Endpoint Descriptor size */USBD_DESC_ENDPOINT,   /* bDescriptorType: Endpoint */0x01,   /* bEndpointAddress: (OUT1) */0x02,   /* bmAttributes: Bulk */VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */0x00,0x00,   /* bInterval: ignore for Bulk transfer *//*Endpoint 1 Descriptor 端点描述符*/0x07,   /* bLength: Endpoint Descriptor size */USBD_DESC_ENDPOINT,   /* bDescriptorType: Endpoint */0x81,   /* bEndpointAddress: (IN1) */0x02,   /* bmAttributes: Bulk */VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */0x00,0x00    /* bInterval */};

3、USB HID报告描述符

const uint8_t s_hidKeyboardReportDescriptor[HID_REPORT_DESCRIPTOR_SIZE] ={/*short Item   D7~D4:bTag;D3~D2:bType;D1~D0:bSize**bTag ---主条目          1000:输入(Input) 1001:输出(Output) 1011:特性(Feature)        1010:集合(Collection) 1100:关集合(End Collection) **                  全局条目         0000:用途页(Usage Page) 0001:逻辑最小值(Logical Minimum) 0010:逻辑最大值(Logical Maximum) 0011:物理最小值(Physical Minimum)**                                        0100:物理最大值(Physical Maximum) 0101:单元指数(Unit Exponet) 0110:单元(Unit) 0111:数据域大小(Report Size)**                                        1000:报告ID(Report ID) 1001:数据域数量(Report Count) 1010:压栈(Push) 1011:出栈(Pop) 1100~1111:保留(Reserved)**                  局部条目        0000:用途(Usage) 0001:用途最小值(Usage Minimum) 0010:用途最大值(Usage Maximum) 0011:标识符索引(Designator Index)**                                        0100:标识符最小值(Designator Minimum) 0101:标识符最大值(Designator Maximum) 0111:字符串索引(String Index) 1000:字符串最小值(String Minimum)   **                                        1001:字符串最大值(String Maximum) 1010:分隔符(Delimiter) 其他:保留(Reserved)**bType---00:主条目(main)  01:全局条目(globle)  10:局部条目(local)  11:保留(reserved)**bSize---00:0字节  01:1字节  10:2字节  11:4字节*///0x05:0000 01 01 这是个全局条目,用途页选择为普通桌面页0x05, 0x01, // USAGE_PAGE (Generic Desktop)//0x09:0000 10 01 这是个全局条目,用途选择为键盘0x09, 0x06, // USAGE (Keyboard)//0xa1:1010 00 01 这是个主条目,选择为应用集合,0xa1, 0x01, // COLLECTION (Application)//0x05:0000 01 11 这是个全局条目,用途页选择为键盘/按键0x05, 0x07, // USAGE_PAGE (Keyboard/Keypad)//0x19:0001 10 01 这是个局部条目,用途的最小值为0xe0,对应键盘上的左ctrl键0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)//0x29:0010 10 01 这是个局部条目,用途的最大值为0xe7,对应键盘上的有GUI(WIN)键0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)//0x15:0001 01 01 这是个全局条目,说明数据的逻辑值最小值为00x15, 0x00, // LOGICAL_MINIMUM (0)//0x25:0010 01 01 这是个全局条目,说明数据的逻辑值最大值为10x25, 0x01, // LOGICAL_MAXIMUM (1)//0x95:1001 01 01 这是个全局条目,数据域的数量为8个0x95, 0x08, // REPORT_COUNT (8)//0x75:0111 01 01 这是个全局条目,每个数据域的长度为1位0x75, 0x01, // REPORT_SIZE (1)           //0x81:1000 00 01 这是个主条目,有8*1bit数据域作为输入,属性为:Data,Var,Abs0x81, 0x02, // INPUT (Data,Var,Abs)//0x95:1001 01 01 这是个全局条目,数据域的数量为1个0x95, 0x01, // REPORT_COUNT (1)//0x75:0111 01 01 这是个全局条目,每个数据域的长度为8位0x75, 0x08, // REPORT_SIZE (8)//0x81:1000 00 01 这是个主条目,有1*8bit数据域作为输入,属性为:Cnst,Var,Abs0x81, 0x03, // INPUT (Cnst,Var,Abs)//0x95:1001 01 01 这是个全局条目,数据域的数量为6个0x95, 0x06, // REPORT_COUNT (6)//0x75:0111 01 01 这是个全局条目,每个数据域的长度为8位0x75, 0x08, // REPORT_SIZE (8)//0x25:0010 01 01 这是个全局条目,逻辑最大值为2550x25, 0xFF, // LOGICAL_MAXIMUM (255)//0x19:0001 10 01 这是个局部条目,用途的最小值为00x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))//0x29:0010 10 01 这是个局部条目,用途的最大值为0x650x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)//0x81:1000 00 01 这是个主条目,有6*8bit的数据域作为输入,属相为属性为:Data,Var,Abs0x81, 0x00, // INPUT (Data,Ary,Abs)//0x25:0010 01 01 这是个全局条目,逻辑的最大值为10x25, 0x01, // LOGICAL_MAXIMUM (1)//0x95:1001 01 01 这是个全局条目,数据域的数量为20x95, 0x02, // REPORT_COUNT (2)//0x75:0111 01 01 这是个全局条目,每个数据域的长度为1位0x75, 0x01, // REPORT_SIZE (1)//0x05:0000 01 01 这是个全局条目,用途页选择为LED页0x05, 0x08, // USAGE_PAGE (LEDs)//0x19:0001 10 01 这是个局部条目,用途的最小值为0x01,对应键盘上的Num Lock0x19, 0x01, // USAGE_MINIMUM (Num Lock)//0x29:0010 10 01 这是个局部条目,用途的最大值为0x02,对应键盘上的Caps Lock0x29, 0x02, // USAGE_MAXIMUM (Caps Lock)//0x91:1001 00 01 这是个主条目,有2*1bit的数据域作为输出,属性为:Data,Var,Abs0x91, 0x02, // OUTPUT (Data,Var,Abs)//0x95:1001 01 01 这是个全局条目,数据域的数量为1个0x95, 0x01, // REPORT_COUNT (1)//0x75:0111 01 01 这是个全局条目,每个数据域的长度为6bit,正好与前面的2bit组成1字节0x75, 0x06, // REPORT_SIZE (6)//0x91:1001 00 01 这是个主条目,有1*6bit数据域最为输出,属性为:Cnst,Var,Abs0x91, 0x03, // OUTPUT (Cnst,Var,Abs)0xc0        // END_COLLECTION};

4、修改端点缓存地址

在 usb_config.h中,调整每个USB端点分配的地址。

#define ENDP0_RXADDR        (0x40)#define ENDP0_TXADDR        (0x80)#define ENDP1_TXADDR        (0xC0)#define ENDP1_RXADDR        (0x0F0)#define ENDP2_TXADDR        (0x110)#define ENDP4_RXADDR        (0x150)#define ENDP4_TXADDR        (0x190)

这时候就完成基本的配置,可以让电脑识别到键盘和虚拟串口的设备,但不能正常使用。

接下来就是代码初始化部分的修改。

基于本来虚拟串口的初始化增加HID配置

void CDC_Init(void){USBD_InitParam_T usbParam;USBD_InitParamStructInit(&usbParam);usbParam.classReqHandler = USBD_ClassHandler;usbParam.stdReqExceptionHandler = KeyBoard_ReportDescriptor;//增加HID配置usbParam.resetHandler = VCP_Reset;usbParam.inEpHandler = USBD_VCP_InEpCallback;usbParam.outEpHandler = USBD_VCP_OutEpCallback;usbParam.pDeviceDesc = (USBD_Descriptor_T *)&g_deviceDescriptor;usbParam.pConfigurationDesc = (USBD_Descriptor_T *)&g_configDescriptor;usbParam.pStringDesc = (USBD_Descriptor_T *)g_stringDescriptor;usbParam.pStdReqCallback = &stdReqCallback;USBD_Init(&usbParam);}void KeyBoard_ReportDescriptor(USBD_DevReqData_T *reqData){uint8_t len;if((reqData->byte.bRequest == USBD_GET_DESCRIPTOR) &&(reqData->byte.bmRequestType.bit.recipient == USBD_RECIPIENT_INTERFACE) &&(reqData->byte.bmRequestType.bit.type == USBD_REQ_TYPE_STANDARD)){if(reqData->byte.wValue[1] == 0x21){len = USB_MIN(reqData->byte.wLength[0], 9);USBD_CtrlInData((uint8_t *)&g_configDescriptor.pDesc[0x12], len);}else if(reqData->byte.wValue[1] == 0x22){len = USB_MIN(reqData->byte.wLength[0], g_ReportDescriptor.size);USBD_CtrlInData((uint8_t *)g_ReportDescriptor.pDesc, len);}}else{USBD_SetEPTxRxStatus(USBD_EP_0, USBD_EP_STATUS_STALL, USBD_EP_STATUS_STALL);}}

到此配置部分基本完成,接下来到main中增加段测试代码,验证USB配置是否正确。

配置虚拟串口一直打印dataBuf[5]= {0xaa,0xbb,0xcc,0xdd,0xff};

HID键盘根据键值表输出数字1


 

void Delay(uint32_t i){while(i--);}unsigned char dataBuf[5]= {0xaa,0xbb,0xcc,0xdd,0xff};uint8_t Keyboad_Buf[8]={0,0,0x1E,0,0,0,0,0};int main(void){CDC_Init();while(1){USBD_TxData(USBD_EP_1, dataBuf, 5);USBD_TxData(USBD_EP_4, Keyboad_Buf, 8);Delay(0xFFFFFF);}}

图片

烧录代码到开发板,接上USB线到电脑,可以看到Bushound能看到配置的复合设备。

图片

使用串口助手能看到虚拟串口能正确打印我们的数据,键盘也正常在发送数字1,证明代码配置没问题,两个功能使用一个USB接口实现了。SDK的虚拟串口也有做接收回传的功能,可以直接使用。

到此键盘+虚拟串口的例程就简单修改完成了。

注:文章作者在原帖中提供了例程文件,有需要请至原文21ic论坛下载

原文地址:https://bbs.21ic.com/icview-3321226-1-1.html

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

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

相关文章

css过渡属性

前言 该属性用于元素各种 “改变” 后的过渡效果动画&#xff0c;包括但不限于颜色、宽高、缩放等。 如下图所示&#xff0c;使用过渡属性便可轻松完成。 示例代码 您可以直接复制运行&#xff0c;查看效果。 <div>demo</div>div {width:100px; height:100px;/* …

云计算核心技术之云存储技术

一、云存储技术1.1、云存储是什么从狭义上来说&#xff0c;云存储是指通过虚拟化、分布式技术、集群应用、网格技术、负载均衡等技术&#xff0c;将网络中大量的存储设备通过软件集合起来高效协同工作&#xff0c;共同对外提供低成本、高扩展性的数据存储服务。从广义上来讲&am…

在Ubuntu上安装并使用Vue2的基本教程

我也准备要尝试一些前端开发了&#xff01;发现网上有些教程写得挺好&#xff0c;但是还是有点老&#xff08;并且有点错误&#xff09;&#xff0c;所以这里更新一下&#xff1a; 主要参考了这篇教程&#xff1a;Vue2——1. 安装教程_vue2 cdn-CSDN博客 并且使用NPM方式进行…

任务十九 打包部署

一、本地打包部署 首先在自己的电脑上,下载一个nginx nginx: download 之后再vscode中,进行打包 输入命令 npm run build 打包过后,会在项目的根目录下,生成一个dist的文件夹

《飞算Java AI使用教程:从安装入门到实践项目》

前引&#xff1a;在当今人工智能技术飞速发展的时代&#xff0c;Java作为企业级开发的主流语言&#xff0c;正与AI技术深度融合。飞算Java AI是一款强大的工具集&#xff0c;旨在帮助开发者轻松构建和部署智能应用&#xff0c;涵盖机器学习、自然语言处理等核心功能。本教程将带…

NestJS 依赖注入方式全解

一、基础注入方式 1. 构造函数注入&#xff08;Constructor Injection&#xff09; 适用场景&#xff1a;模块间依赖传递&#xff0c;服务初始化时必须存在的依赖 实现方式&#xff1a;通过构造函数参数声明依赖&#xff0c;NestJS 自动解析并注入 Injectable() class UserServ…

完整源码+技术文档!基于Hadoop+Spark的鲍鱼生理特征大数据分析系统免费分享

&#x1f393; 作者&#xff1a;计算机毕设小月哥 | 软件开发专家 &#x1f5a5;️ 简介&#xff1a;8年计算机软件程序开发经验。精通Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等技术栈。 &#x1f6e0;️ 专业服务 &#x1f6e0;️ 需求定制化开发源码提…

云原生俱乐部-shell知识点归纳(1)

shell的内容也挺多的&#xff0c;虽然云原生课程主要是讲grep、sed、awk三剑客&#xff0c;但是还有结合循环结构&#xff0c;判断语句&#xff0c;以及函数等内容。还是有点复杂的&#xff0c;并且我对shell的掌握并不多&#xff0c;所以写的可能并不全。当然&#xff0c;如果…

设计模式(四)——责任链模式

1. 责任链模式的定义 责任链模式&#xff08;Chain of Responsibility&#xff0c;简称 CoR&#xff0c;也叫职责链模式&#xff09;是一种行为型设计模式&#xff0c;允许一个请求在一系列处理器&#xff08;handlers&#xff09;中传递。每个处理器可以选择自己处理该请求&am…

MyBatis-Plus基础篇详解

文章目录前言一、简单介绍MyBatis-Plus1.1 特性1.2 架构二、SpringBoot集成MyBatis-Plus2.1 项目搭建2.2 导入所需依赖2.3 配置application.yml2.4 创建实体类2.5 创建Mapper接口2.6 启动类配置三、DQL操作3.1 基础查询3.2 QueryWrapper查询3.3 LambdaQueryWrapper查询3.4 分页…

基于W55MH32Q-EVB 实现 HTTP 服务器配置 OLED 滚动显示信息

目录 1 前言 2 项目环境 2.1 硬件准备 2.2 软件环境 3.硬件连接和方案 3.1 硬件连接 3.2 方案图示 4.例程修改 1 前言 HTTP&#xff08;超文本传输协议&#xff0c;HyperText Transfer Protocol&#xff09;是一种用于分布式、协作式、超媒体信息系统的应用层协议&#xff0c; …

YggJS RLogin暗黑霓虹主题登录注册页面 版本:v0.1.1

项目介绍 yggjs_rlogin 是一个专注于 React 登录/注册页面的组件库。本文档介绍“暗黑霓虹”主题&#xff1a;#111 暗色背景 青蓝霓虹描边输入框 赛博朋克光效按钮。 安装说明 安装&#xff1a;pnpm add yggjs_rlogin react react-dom使用&#xff1a;从 yggjs_rlogin 引入组…

大数据毕业设计选题推荐:护肤品店铺运营数据可视化分析系统详解

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

【github-action 如何为github action设置secrets/environment】

Using secrets in GitHub Actions 在 GitHub Actions 中使用密钥 Learn how to create secrets at the repository, environment, and organization levels for GitHub Actions workflows. 学习如何在仓库、环境和组织级别为 GitHub Actions 工作流创建密钥。 Creating secre…

宝塔面板Docker安装n8n汉化中文

一、Docker安装N8N 安装配置默认即可&#xff0c;如果端口已被使用&#xff0c;可以自行更改 当状态为运行中时&#xff0c;就可以点击端口&#xff1a;访问N8N 填写完信息后&#xff0c;点击下一步&#xff08;邮箱要能接收邮件&#xff1a;接收密钥&#xff09; 点开始 点击发…

F003疫情传染病数据可视化vue+flask+mysql

编号:F003 文章结尾有CSDN官方提供的学长的联系方式&#xff01;&#xff01; 欢迎关注B站 ✅ vue flask 前后端分离架构 ✅ 实现中国地图、柱状图、折线图、水地图、环图等多种图形的echarts可视化分析 视频 vueflask爬虫 新冠疫情大屏实现 python 可视化分析项目源码1 系统…

plantsimulation知识点25.8.19 工件不在RGV中心怎么办?

如果出现这种情况&#xff0c;工件不在RGV的中心该怎么处理。首先说一下出现这种情况的原因。因为模拟的是两台RGV共同托举一个工件移动&#xff0c;实际上RGV控制的代码还是写在一条轨道的传感器控制代码中。另一台RGV只是从动的&#xff0c;工件也是在其中任意一台RGV上&…

redis-sentinel基础概念及部署

一. 引言&#xff1a;Redis Sentinel 是 redis 官方提供的高可用解决方案&#xff0c;主要用于监控 Redis 主从集群&#xff0c;在主节点故障时自动完成故障转移&#xff0c;确保服务持续可用。二. 核心功能1. 监控&#xff08;monitoring&#xff09;&#xff1a;持续检查主节…

LangChain RAG 简述

在 LangChain 中实现 RAG&#xff08;检索增强生成&#xff0c;Retrieval-Augmented Generation&#xff09;的核心思路是&#xff1a;让大模型在生成回答前&#xff0c;先从外部知识库&#xff08;如文档、数据库等&#xff09;中检索相关信息&#xff0c;再基于检索到的内容生…

GEO 优化专家孟庆涛:技术破壁者重构 AI 时代搜索逻辑

在生成式 AI 重塑全球搜索生态的浪潮中&#xff0c;中国 GEO&#xff08;生成式引擎优化&#xff09;领域的开拓者孟庆涛以 "智能决策革命" 的技术框架&#xff0c;颠覆了传统 "发发文章" 的简单认知。作为辽宁粤穗网络科技有限公司总经理兼 GEO 实验室主任…