USB HOST移植

一、USB简介

        USB有USB1.0/1.1/2.0/3.0多个版本,标准USB由4根线组成,VCC,GND,D+,D-,其中D+和D-是数据线,采用差分传输。

       在USB主机上,D-和D+都是接了15K的电阻到地,所以在没有设备接入的时候,D+、D-均是低电平。而在USB设备中,如果是高速设备,则会在D+上接一个1.5K的电阻到VCC,而如果是低速设备,则会在D-上接一个1.5K的电阻到VCC,当设备接入主机时,主机就可以判断是否有设备接入,并能判断设备是高速设备还是低速设备。

        DualCore:这通常指的是一个USB设备具有双核处理器,即设备内部有两个处理器核心,可以提高设备的处理性能和效率。

        HID(Human Interface Device):这是指一种USB设备类型,用于与人类交互,例如键盘、鼠标、游戏手柄等。

        MSC(Mass Storage Class):这是指一种USB设备类型,用于存储数据,例如闪存驱动器、移动硬盘等。

二、资料准备

(1)SD卡带文件系统的基本工程

(2)USB源码

链接:https://pan.baidu.com/s/1Cy1WokfpHBpDONfbqT_wgQ?pwd=8888 
提取码:8888

三、移植过程

四、修改错误

编译,报12个错误,从第一个错误解决(解决完一个问题可以尝试编译以下)

(1)添加头文件 #include "stm32f4xx.h"

(2)添加宏定义 USE_USB_OTG_FS

(3)修改usbh_usr.c和usbh_usr.h文件

#include "usbh_usr.h" 
#include "ff.h" 
#include "usart.h" static u8 AppState;
extern USB_OTG_CORE_HANDLE  USB_OTG_Core;//USB OTG 中断服务函数
//处理所有USB中断
void OTG_FS_IRQHandler(void)
{USBH_OTG_ISR_Handler(&USB_OTG_Core);
} 
//USB HOST 用户回调函数.
USBH_Usr_cb_TypeDef USR_Callbacks=
{USBH_USR_Init,USBH_USR_DeInit,USBH_USR_DeviceAttached,USBH_USR_ResetDevice,USBH_USR_DeviceDisconnected,USBH_USR_OverCurrentDetected,USBH_USR_DeviceSpeedDetected,USBH_USR_Device_DescAvailable,USBH_USR_DeviceAddressAssigned,USBH_USR_Configuration_DescAvailable,USBH_USR_Manufacturer_String,USBH_USR_Product_String,USBH_USR_SerialNum_String,USBH_USR_EnumerationDone,USBH_USR_UserInput,USBH_USR_MSC_Application,USBH_USR_DeviceNotSupported,USBH_USR_UnrecoveredError
};
/
//以下为各回调函数实现.//USB HOST 初始化 
void USBH_USR_Init(void)
{printf("USB OTG HS MSC Host\r\n");printf("> USB Host library started.\r\n");printf("  USB Host Library v2.1.0\r\n\r\n");}
//检测到U盘插入
void USBH_USR_DeviceAttached(void)//U盘插入
{printf("检测到USB设备插入!\r\n");
}
//检测到U盘拔出
void USBH_USR_DeviceDisconnected (void)//U盘移除
{printf("USB设备拔出!\r\n");
}  
//复位从机
void USBH_USR_ResetDevice(void)
{printf("复位设备...\r\n");
}
//检测到从机速度
//DeviceSpeed:从机速度(0,1,2 / 其他)
void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed)
{if(DeviceSpeed==HPRT0_PRTSPD_HIGH_SPEED){printf("高速(HS)USB设备!\r\n");}  else if(DeviceSpeed==HPRT0_PRTSPD_FULL_SPEED){printf("全速(FS)USB设备!\r\n"); }else if(DeviceSpeed==HPRT0_PRTSPD_LOW_SPEED){printf("低速(LS)USB设备!\r\n");  }else{printf("设备错误!\r\n");  }
}
//检测到从机的描述符
//DeviceDesc:设备描述符指针
void USBH_USR_Device_DescAvailable(void *DeviceDesc)
{ USBH_DevDesc_TypeDef *hs;hs=DeviceDesc;   printf("VID: %04Xh\r\n" , (uint32_t)(*hs).idVendor); printf("PID: %04Xh\r\n" , (uint32_t)(*hs).idProduct); 
}
//从机地址分配成功
void USBH_USR_DeviceAddressAssigned(void)
{printf("从机地址分配成功!\r\n");   
}
//配置描述符获有效
void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef * cfgDesc,USBH_InterfaceDesc_TypeDef *itfDesc,USBH_EpDesc_TypeDef *epDesc)
{USBH_InterfaceDesc_TypeDef *id; id = itfDesc;   if((*id).bInterfaceClass==0x08){printf("可移动存储器设备!\r\n"); }else if((*id).bInterfaceClass==0x03){printf("HID 设备!\r\n"); }    
}
//获取到设备Manufacturer String
void USBH_USR_Manufacturer_String(void *ManufacturerString)
{printf("Manufacturer: %s\r\n",(char *)ManufacturerString);
}
//获取到设备Product String 
void USBH_USR_Product_String(void *ProductString)
{printf("Product: %s\r\n",(char *)ProductString);  
}
//获取到设备SerialNum String 
void USBH_USR_SerialNum_String(void *SerialNumString)
{printf("Serial Number: %s\r\n",(char *)SerialNumString);    
} 
//设备USB枚举完成
void USBH_USR_EnumerationDone(void)
{ printf("设备枚举完成!\r\n\r\n");    
} 
//无法识别的USB设备
void USBH_USR_DeviceNotSupported(void)
{printf("无法识别的USB设备!\r\n\r\n");    
}  
//等待用户输入按键,执行下一步操作
USBH_USR_Status USBH_USR_UserInput(void)
{ printf("跳过用户确认步骤!\r\n");return USBH_USR_RESP_OK;
} 
//USB接口电流过载
void USBH_USR_OverCurrentDetected (void)
{printf("端口电流过大!!!\r\n");
} extern u8 USH_User_App(void);		//用户测试主程序
//USB HOST MSC类用户应用程序
int USBH_USR_MSC_Application(void)
{u8 res=0;switch(AppState){case USH_USR_FS_INIT://初始化文件系统 printf("开始执行用户程序!!!\r\n");AppState=USH_USR_FS_TEST;break;case USH_USR_FS_TEST:	//执行USB OTG 测试主程序res=USH_User_App(); //用户主程序res=0;if(res)AppState=USH_USR_FS_INIT;break;default:break;} return res;
}
//用户要求重新初始化设备
void USBH_USR_DeInit(void)
{AppState=USH_USR_FS_INIT;
}
//无法恢复的错误!!  
void USBH_USR_UnrecoveredError (void)
{printf("无法恢复的错误!!!\r\n\r\n");	
}//用户定义函数,实现fatfs diskio的接口函数 
extern USBH_HOST              USB_Host;//获取U盘状态
//返回值:0,U盘未就绪
//      1,就绪
u8 USBH_UDISK_Status(void)
{return HCD_IsDeviceConnected(&USB_OTG_Core);//返回U盘状态
}//读U盘
//buf:读数据缓存区
//sector:扇区地址
//cnt:扇区个数	
//返回值:错误状态;0,正常;其他,错误代码;		 
u8 USBH_UDISK_Read(u8* buf,u32 sector,u32 cnt)
{u8 res=1;if(HCD_IsDeviceConnected(&USB_OTG_Core)&&AppState==USH_USR_FS_TEST)//连接还存在,且是APP测试状态{  		    do{res=USBH_MSC_Read10(&USB_OTG_Core,buf,sector,512*cnt);USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);		      if(!HCD_IsDeviceConnected(&USB_OTG_Core)){res=1;//读写错误break;};   }while(res==USBH_MSC_BUSY);}else res=1;		  if(res==USBH_MSC_OK)res=0;	return res;
}//写U盘
//buf:写数据缓存区
//sector:扇区地址
//cnt:扇区个数	
//返回值:错误状态;0,正常;其他,错误代码;		 
u8 USBH_UDISK_Write(u8* buf,u32 sector,u32 cnt)
{u8 res=1;if(HCD_IsDeviceConnected(&USB_OTG_Core)&&AppState==USH_USR_FS_TEST)//连接还存在,且是APP测试状态{  		    do{res=USBH_MSC_Write10(&USB_OTG_Core,buf,sector,512*cnt); USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);		      if(!HCD_IsDeviceConnected(&USB_OTG_Core)){res=1;//读写错误break;};   }while(res==USBH_MSC_BUSY);}else res=1;		  if(res==USBH_MSC_OK)res=0;	return res;
}

/********************************************************************************* @file    usbh_usr.h* @author  MCD Application Team* @version V2.1.0* @date    19-March-2012* @brief   Header file for usbh_usr.c******************************************************************************* @attention** <h2><center>&copy; COPYRIGHT 2012 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.********************************************************************************/ /* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USH_USR_H__
#define __USH_USR_H__/* Includes ------------------------------------------------------------------*/
#include "ff.h"
#include "usbh_core.h"
#include "usb_conf.h"
#include <stdio.h>
#include "usbh_msc_core.h"
#include "usb_hcd_int.h"/** @addtogroup USBH_USER* @{*//** @addtogroup USBH_MSC_DEMO_USER_CALLBACKS* @{*//** @defgroup USBH_USR* @brief This file is the Header file for usbh_usr.c* @{*/ /** @defgroup USBH_USR_Exported_Types* @{*/ extern  USBH_Usr_cb_TypeDef USR_Callbacks;/*** @}*/ /** @defgroup USBH_USR_Exported_Defines* @{*/ 
/* State Machine for the USBH_USR_ApplicationState */
#define USH_USR_FS_INIT       	0
#define USH_USR_FS_TEST   		1  /*** @}*/ /** @defgroup USBH_USR_Exported_Macros* @{*/ 
/*** @}*/ /** @defgroup USBH_USR_Exported_Variables* @{*/ 
extern  uint8_t USBH_USR_ApplicationState ;
/*** @}*/ /** @defgroup USBH_USR_Exported_FunctionsPrototype* @{*/ 
void USBH_USR_ApplicationSelected(void);
void USBH_USR_Init(void);
void USBH_USR_DeInit(void);
void USBH_USR_DeviceAttached(void);
void USBH_USR_ResetDevice(void);
void USBH_USR_DeviceDisconnected (void);
void USBH_USR_OverCurrentDetected (void);
void USBH_USR_DeviceSpeedDetected(uint8_t DeviceSpeed); 
void USBH_USR_Device_DescAvailable(void *);
void USBH_USR_DeviceAddressAssigned(void);
void USBH_USR_Configuration_DescAvailable(USBH_CfgDesc_TypeDef * cfgDesc,USBH_InterfaceDesc_TypeDef *itfDesc,USBH_EpDesc_TypeDef *epDesc);
void USBH_USR_Manufacturer_String(void *);
void USBH_USR_Product_String(void *);
void USBH_USR_SerialNum_String(void *);
void USBH_USR_EnumerationDone(void);
USBH_USR_Status USBH_USR_UserInput(void);
void USBH_USR_DeInit(void);
void USBH_USR_DeviceNotSupported(void);
void USBH_USR_UnrecoveredError(void);
int USBH_USR_MSC_Application(void);u8 USBH_UDISK_Status(void);
u8 USBH_UDISK_Read(u8* buf,u32 sector,u32 cnt);
u8 USBH_UDISK_Write(u8* buf,u32 sector,u32 cnt);/*** @}*/ #endif /*__USH_USR_H__*//*** @}*/ /*** @}*/ /*** @}*/ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 编译之后只存在3个错误

(4)修改diski.c文件,添加对U盘的访问

/*-----------------------------------------------------------------------*/
/* Low level disk I/O module SKELETON for FatFs     (C)ChaN, 2019        */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be        */
/* attached to the FatFs via a glue function rather than modifying it.   */
/* This is an example of glue functions to attach various exsisting      */
/* storage control modules to the FatFs module with a defined API.       */
/*-----------------------------------------------------------------------*/#include "ff.h"			/* Obtains integer types */
#include "diskio.h"		/* Declarations of disk functions */
#include "sdio_sdcard.h"
#include "usbh_usr.h" /* Definitions of physical drive number for each drive */#define DEV_MMC		0	/* Example: Map MMC/SD card to physical drive 0 */
#define DEV_USB		1	/* Example: Map USB MSD to physical drive 1 */
#define DEV_RAM		2	/* Example: Map Ramdisk to physical drive 2 *//*-----------------------------------------------------------------------*/
/* Get Drive Status                                                      */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (BYTE pdrv		/* Physical drive nmuber to identify the drive */
)
{switch (pdrv) {case DEV_RAM :break;case DEV_MMC :return 0;case DEV_USB :return 0;}return STA_NOINIT;
}/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/DSTATUS disk_initialize (BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{int result;switch (pdrv) {case DEV_RAM :break;case DEV_MMC :result = SD_Init();if(result==0)	return 0;break;case DEV_USB :if(USBH_UDISK_Status())return 0;	//U盘连接成功,则返回1.否则返回0		  break;}return STA_NOINIT;
}/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/DRESULT disk_read (BYTE pdrv,		/* Physical drive nmuber to identify the drive */BYTE *buff,		/* Data buffer to store read data */LBA_t sector,	/* Start sector in LBA */UINT count		/* Number of sectors to read */
)
{int result;switch (pdrv) {case DEV_RAM :break;case DEV_MMC :result=SD_ReadDisk(buff,sector,count);	 while(result)//读出错{SD_Init();	//重新初始化SD卡result=SD_ReadDisk(buff,sector,count);	}return 0;case DEV_USB :result=USBH_UDISK_Read(buff,sector,count);	  if(result==0)	return 0;}return RES_PARERR;
}/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/#if FF_FS_READONLY == 0DRESULT disk_write (BYTE pdrv,			/* Physical drive nmuber to identify the drive */const BYTE *buff,	/* Data to be written */LBA_t sector,		/* Start sector in LBA */UINT count			/* Number of sectors to write */
)
{int res;switch (pdrv) {case DEV_RAM :break;case DEV_MMC :res=SD_WriteDisk((u8*)buff,sector,count);while(res)//写出错{SD_Init();	//重新初始化SD卡res=SD_WriteDisk((u8*)buff,sector,count);	//printf("sd wr error:%d\r\n",res);}return 0;case DEV_USB :res=USBH_UDISK_Write((u8*)buff,sector,count); if(res==0)	return 0;break;}return RES_PARERR;
}#endif/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/DRESULT disk_ioctl (BYTE pdrv,		/* Physical drive nmuber (0..) */BYTE cmd,		/* Control code */void *buff		/* Buffer to send/receive control data */
)
{int res=0;switch (pdrv) {case DEV_RAM :break;case DEV_MMC :res=1;switch(cmd){case CTRL_SYNC:res = RES_OK; break;	 case GET_SECTOR_SIZE:*(DWORD*)buff = 512; res = RES_OK;break;	 case GET_BLOCK_SIZE:*(WORD*)buff = SDCardInfo.CardBlockSize;res = RES_OK;break;	 case GET_SECTOR_COUNT:*(DWORD*)buff = SDCardInfo.CardCapacity/512;res = RES_OK;break;default:res = RES_PARERR;break;}case DEV_USB :res=1;switch(cmd){case CTRL_SYNC:res = RES_OK; break;	 case GET_SECTOR_SIZE:*(WORD*)buff=512;res = RES_OK;break;	 case GET_BLOCK_SIZE:*(WORD*)buff=512;res = RES_OK;break;	 case GET_SECTOR_COUNT:*(DWORD*)buff=USBH_MSC_Param.MSCapacity;res = RES_OK;break;default:res = RES_PARERR;break;}	}if(res==1) return 0;return RES_PARERR;
}DWORD get_fattime (void)
{				 return 0;
}	

(5)修改ffconf.h文件,将_VOLUME的值改成2,以支持2个磁盘(SD卡和U盘)

#define FF_VOLUMES		2//支持2个磁盘(SD卡和U盘)

(6)修改usb_bsp.c文件

#include "usb_bsp.h"
#include "sys.h"
#include "delay.h"//USB主机电源控制口
#define USB_HOST_PWRCTRL 	PAout(15)	//PA15void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA , ENABLE);  RCC_AHB2PeriphClockCmd( RCC_AHB2Periph_OTG_FS , ENABLE);  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;GPIO_Init(GPIOA, &GPIO_InitStructure);  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;GPIO_Init(GPIOA, &GPIO_InitStructure);    USB_HOST_PWRCTRL=1;			//开启USB HOST电源供电GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_OTG_FS);GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_OTG_FS);
}void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev)
{NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;NVIC_InitStructure.NVIC_IRQChannelSubPriority =0x03;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);  }//USB OTG 中断设置,开启USB FS中断
//pdev:USB OTG内核结构体指针
void USB_OTG_BSP_DisableInterrupt(void)
{ 
}//USB OTG 端口供电设置(本例程未用到)
//pdev:USB OTG内核结构体指针
//state:0,断电;1,上电
void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev, uint8_t state)
{ 
}//USB_OTG 端口供电IO配置(本例程未用到)
//pdev:USB OTG内核结构体指针
void  USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev)
{ 
} //USB_OTG us级延时函数
//本例程采用SYSTEM文件夹的delay.c里面的delay_us函数实现
//官方例程采用的是定时器2来实现的.
//usec:要延时的us数.
void USB_OTG_BSP_uDelay (const uint32_t usec)
{ delay_us(usec);
}//USB_OTG ms级延时函数
//本例程采用SYSTEM文件夹的delay.c里面的delay_ms函数实现
//官方例程采用的是定时器2来实现的.
//msec:要延时的ms数.
void USB_OTG_BSP_mDelay (const uint32_t msec)
{  delay_ms(msec);
}

五、main.c函数 

USBH_HOST  USB_Host;
USB_OTG_CORE_HANDLE  USB_OTG_Core;FATFS fs[2];//U盘插入以后,实现用户需要实现的功能
//返回值:0,正常
//       1,有问题
u8 USH_User_App(void)
{ u8 result=0;printf("USB设备连接成功\r\n");	 result=f_mount(&fs[1],"1:",1); 	//重新挂载U盘printf("f_mount %d\r\n",result);while(HCD_IsDeviceConnected(&USB_OTG_Core))//只要U盘是连接状态,则一直执行while循环{	}f_mount(0,"1:",1); 	//卸载U盘printf("USB设备连接中\r\n");	 return result;
} main()
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2delay_init(168);  //初始化延时函数uart_init(115200);		//初始化串口波特率为115200//初始化USB主机USBH_Init(&USB_OTG_Core,USB_OTG_FS_CORE_ID,&USB_Host,&USBH_MSC_cb,&USR_Callbacks);  while(1){USBH_Process(&USB_OTG_Core, &USB_Host);//用于实现USB主机通信的核心状态机处理,该函数必须被循环调用,而且调用频率越快越好,以便及时处理各种事务}
}

六、测试结果

完整工程代码

链接:https://pan.baidu.com/s/1-zBpkGQRTFZnnn-ZNXB3dg
提取码:生日

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

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

相关文章

Vue js封装接口

天梦星服务平台 (tmxkj.top)https://tmxkj.top/#/ 1.安装axios npm install axios -g 2.在src下新建一个Api文件夹,再创建一个js文件 import axios from axios let configuration {url:"http://localhost:9090" } /*** 请求项目数据的请求体*/ async function h…

QGraphicsView(平移/缩放/旋转)

简述 Graphics View提供了一个平台&#xff0c;用于大量自定义 2D 图元的管理与交互&#xff0c;框架包括一个事件传播架构&#xff0c;支持场景 Scene 中的图元 Item 进行精确的双精度交互功能。Item 可以处理键盘事件、鼠标按下、移动、释放和双击事件&#xff0c;同时也能跟…

地推网推拉新是什么意思?地推网推拉新区别最全介绍

地推是相对于网推的&#xff0c;主要是通过线下推广&#xff0c;来吸引客户注册等拉新操作&#xff0c;有时会发一些小礼物之类的&#xff0c;在之前地推是最早获取新用户的方式&#xff0c;是最有效的拉新方式&#xff0c;直到现在地推仍是各类互联网公司和品牌商家&#xff0…

论文阅读之PeriodicLoRA: Breaking the Low-Rank Bottleneck in LoRA Optimization(2024)

文章目录 论文地址主要内容主要贡献模型图技术细节实验结果 论文地址 PeriodicLoRA: Breaking the Low-Rank Bottleneck in LoRA Optimization 主要内容 这篇文章的主要内容是介绍了一种名为PeriodicLoRA&#xff08;PLoRA&#xff09;的参数高效微调&#xff08;Parameter-…

sdrangel下载与部署for windows

下载 https://github.com/f4exb/sdrangel 在其目录下新建build文件 部署 打开cmake软件,修改如下 点击下面Configure,选择对应vs版本 点击finish,按照提示报错信息配置即可 ARCH_OPT=SSE4_2 DEBUG_OUTPUT

qt table 简易封装,样式美化,以及 合并表格和颜色的区分 已解决

在需求中&#xff0c; 难免会使用 table 进行渲染窗口&#xff0c;做一个简单的封装。美化表格最终效果&#xff01;&#xff01;&#xff01; 代码部分 // 显示 20行 20列CCendDetailsInfoTableWidget* table new CCendDetailsInfoTableWidget(20,10);for (int i 0; i < …

基于Springboot Vue医院管理系统+数据库脚本+文档(万字)

项目效果视频: 基于Springboot Vue医院管理系统 一、 项目介绍 角色&#xff1a;管理员、患者、医生 基于springboot vue实现的医院管理系统&#xff0c;有管理员、医生和患者三种角色。系统拥有丰富的功能&#xff0c;能够满足各类用户的需求&#xff0c;系统提供了登录和注册…

[Qt学习笔记]Qt实现自定义控件SwitchButton开关按钮

1、功能介绍 在项目UI中使用较多的打开/关闭的开关按钮&#xff0c;一般都是找图片去做效果&#xff0c;比如说如下的图像来表征打开或关闭。 如果想要控件有打开/关闭的动画效果或比较好的视觉效果&#xff0c;这里就可以使用自定义控件&#xff0c;使用Painter来绘制控件。软…

001-Windows下PyTorch极简开发环境配置

本节介绍Windows系统下配置一套基于Pytorch框架的极简深度学习开发环境。 目录 0.1 缘起 0.2 准备 1.1 安装Anaconda 1.2 安装CUDA和cudnn &#xff08;1&#xff09;确定CUDA版本 &#xff08;2&#xff09;安装CUDA &#xff08;3&#xff09;安装cudnn 1.3 安装Pyt…

论文阅读--临床驱动的多标签医学图像分类中的三元组注意力与双池对比学习---TA-DCL

来源&#xff1a;https://github.com/ZhangYH0502/TA-DCL. 模型结合了两种技术&#xff1a;三元组注意力&#xff08;Triplet attention&#xff09;和双池对比学习&#xff08;Dual-pool contrastive learning&#xff09;。这个模型是为了解决临床应用中多标签医学图像分类问…

中等职业学校大数据课程建设方案

大数据产业是以数据及数据所蕴含的信息价值为核心生产要素&#xff0c;通过数据技术、数据产品、数据服务等形式&#xff0c;使数据与信息价值在各行业经济活动中得到充分释放的赋能型产业。 大数据产业定义一般分为核心业态、关联业态、衍生业态三大业态。 一、专…

C语言 青蛙跳台阶问题

目录 ​编辑 1.问题描述 2.问题分析 3.全部代码 4.结语 1.问题描述 一只青蛙可以一次跳一级台阶&#xff0c;也可以一次跳两级台阶&#xff0c;如果青蛙要跳上n级台阶有多少种跳法&#xff1f; 2.问题分析 当台阶只有一级时&#xff0c;只能跳一级&#xff0c;所以只有一…