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
}