MCU型号:STM32F107
开发环境:MDK4
U盘大小:8GB
FAT:R0.08A
最终效果如下所示:
代码解析:
1.main.c
int main(void) { BSP_Init(); /* Init Host Library */ USBH_Init(&USB_OTG_FS_dev, &MSC_cb , &USR_Callbacks); while (1) { /* Host Task handler */ USBH_Process(); } }
BSP_Init()//使用到的硬件初始化
USBH_Init//USB有关的初始化
USBH_Process();//USB处理函数
2.USB初始化相关代码
voidUSBH_Init(USB_OTG_CORE_HANDLE *pdev, USBH_Class_cb_TypeDef *class_cb, USBH_Usr_cb_TypeDef *usr_cb) { printf("into USBH_Init()\r\n"); /* Hardware Init */ USB_OTG_BSP_Init(); printf("1\r\n"); /* Intialize Timer for delay function */ //USB_OTG_BSP_TimeInit(); printf("2\r\n"); /* configure GPIO pin used for switching VBUS power */ USB_OTG_BSP_ConfigVBUS(); printf("3\r\n"); /* Host de-initializations */ USBH_DeInit(); printf("4\r\n"); /*Register class and user callbacks */ USBH_Machine.class_cb = class_cb; USBH_Machine.usr_cb = usr_cb; USBH_Machine.conn_cb = &USBH_DeviceConnStatus_cb; USBH_Machine.Control.hc_num_out = USBH_Alloc_Channel(&USB_OTG_FS_dev,0x00); USBH_Machine.Control.hc_num_in = USBH_Alloc_Channel(&USB_OTG_FS_dev,0x80); USBH_Machine.conn_cb->ConnStatus = 0; USBH_Machine.conn_cb->DisconnStatus = 0; printf("5\r\n"); /* Start the USB OTG FS core */ HCD_Init(pdev); printf("6\r\n"); /* Upon Init call usr call back */ USBH_Machine.usr_cb->Init(); printf("7\r\n"); /* Enable Interrupts */ USB_OTG_BSP_EnableInterrupt(); }
2.1USB_OTG_BSP_Init()函数 初始化USB时钟引脚中断等
void USB_OTG_BSP_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; /* Select USBCLK source */ RCC_OTGFSCLKConfig(RCC_OTGFSCLKSource_PLLVCO_Div3); /* Enable the USB clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE) ; RCC_APB2PeriphClockCmd( KEYA_PORT_RCC | KEYB_PORT_RCC | KEYC_PORT_RCC,ENABLE); #ifdef SOF_OUTPUT_ENABLED /* To enable SOF pulse out on PAD */ RCC_APB2PeriphClockCmd(HOST_SOF_OUTPUT_RCC, ENABLE); /* Configure SOF Pin */ GPIO_InitStructure.GPIO_Pin = HOST_SOF_SIGNAL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(HOST_SOF_PORT, &GPIO_InitStructure); #endif /* Configure pin for overcurrent detection */ #ifdef OVERCURRENT_DET RCC_APB2PeriphClockCmd(HOST_OVRCURR_PORT_RCC, ENABLE); /* Configure SOF Pin */ GPIO_InitStructure.GPIO_Pin = HOST_OVRCURR_LINE; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(HOST_OVRCURR_PORT, &GPIO_InitStructure); /* Connect Button EXTI Line to Button GPIO Pin */ GPIO_EXTILineConfig(HOST_OVRCURR_PORT_SOURCE,HOST_OVRCURR_PIN_SOURCE); /* Configure Button EXTI line */ EXTI_InitStructure.EXTI_Line = HOST_OVRCURR_EXTI_LINE; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); #endif //zjk: enable usb_H pwr PE.15 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOE, &GPIO_InitStructure); GPIO_SetBits(GPIOE , GPIO_Pin_15) ; }
2.2USB_OTG_BSP_ConfigVBUS();//VBUS引脚初始化
void USB_OTG_BSP_ConfigVBUS(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(HOST_POWERSW_PORT_RCC, ENABLE); /* Configure Power Switch Vbus Pin */ GPIO_InitStructure.GPIO_Pin = HOST_POWERSW_VBUS; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(HOST_POWERSW_PORT, &GPIO_InitStructure); /* By Default, DISABLE is needed on output of the Power Switch */ GPIO_ResetBits(HOST_POWERSW_PORT, HOST_POWERSW_VBUS); USB_OTG_BSP_mDelay(200); /*Delay is need for stabilising the Vbus Low in Reset Condition, when Vbus=1 and Reset-button is pressed by user */ }
2.3USBH_DeInit();//参数初始化
static USBH_StatusUSBH_DeInit(void) { /* Software Init */ USBH_Machine.gState = HOST_IDLE; USBH_Machine.gStateBkp = HOST_IDLE; USBH_Machine.EnumState = ENUM_IDLE; USBH_Machine.RequestState = CMD_SEND; USBH_Machine.Control.state = CTRL_SETUP; USBH_Machine.Control.ep0size = USB_OTG_MAX_EP0_SIZE; USBH_Device.address = USBH_DEVICE_ADDRESS_DEFAULT; USBH_Device.speed = HPRT0_PRTSPD_FULL_SPEED; return USBH_OK; }
2.4 回调函数赋值地址
2.5HCD_Init(pdev);//
uint32_t HCD_Init(USB_OTG_CORE_HANDLE*pdev) { pdev->host.ConnSts = 0; pdev->host.ErrCnt = 0; pdev->host.XferCnt = 0; pdev->host.HC_Status =HC_IDLE; pdev->host.hc[0].max_packet =8; USB_OTG_CoreInit(pdev); /* Force Host Mode*/ USB_OTG_SetHostMode(pdev); USBotg_OTG_CoreInitHost(pdev); USB_OTG_EnableGlobalInt(pdev); return 0; }
2.6USB_OTG_BSP_EnableInterrupt();//中断使能
voidUSB_OTG_BSP_EnableInterrupt(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Enable USB Interrupt */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #ifdef OVERCURRENT_DET /* Enable the Overcurrent Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = HOST_OVRCURR_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif }