調試USB例題需要用到2個上位機程序:
PC端HID交互程序,提供了VC源程序。
圖形方式的按鈕輸入、LED輸出操作:
總線撲捉器:
main程序初始化部分很簡單:
/* Initialize USB */
USBD_Init(&USB_Device_dev,
&USR_desc,
&USBD_HID_cb,
&USR_cb);
打開 usbd_custom_hid_core.c
這個數據結構是用戶關心的
USBD_Class_cb_TypeDef USBD_HID_cb =
{
USBD_HID_Init,
USBD_HID_DeInit,
USBD_HID_Setup,
NULL, /*EP0_TxSent*/
USBD_HID_EP0_RxReady, /*EP0_RxReady*/ /* STATUS STAGE IN */
USBD_HID_DataIn, /*DataIn*/ 輸入輸出調用程序
USBD_HID_DataOut, /*DataOut*/
NULL, /*SOF */
USBD_HID_GetCfgDesc,
};
USB接收數據處理:
打開 usbd_custom_hid_core.c
找到這個程序,可以看出根據上位機發來的數據參數,分別點亮不同的LED
/**
* @brief USBD_HID_DataOut
* handle data IN Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
uint8_t USBD_HID_DataOut (void *pdev,
uint8_t epnum)
{
BitAction Led_State;
if (epnum == 1)
{
if (Report_buf[1] == 0)
{
Led_State = Bit_RESET;
}
else
{
Led_State = Bit_SET;
}
switch (Report_buf[0])
{
case 1: /* Led 3 */
if (Led_State != Bit_RESET)
{
STM_EVAL_LEDOn(LED3);
}
else
{
STM_EVAL_LEDOff(LED3);
}
break;
case 2: /* Led 4 */
if (Led_State != Bit_RESET)
{
STM_EVAL_LEDOn(LED4);
}
else
{
STM_EVAL_LEDOff(LED4);
}
break;
case 3: /* Led 5 */
if (Led_State != Bit_RESET)
{
STM_EVAL_LEDOn(LED5);
}
else
{
STM_EVAL_LEDOff(LED5);
}
break;
case 4: /* Led 6 */
if (Led_State != Bit_RESET)
{
STM_EVAL_LEDOn(LED6);
}
else
{
STM_EVAL_LEDOff(LED6);
}
break;
default:
STM_EVAL_LEDOff(LED3);
STM_EVAL_LEDOff(LED4);
STM_EVAL_LEDOff(LED5);
STM_EVAL_LEDOff(LED6);
break;
}
}
DCD_EP_PrepareRx(pdev,HID_IN_EP,Report_buf,2);
return USBD_OK;
}
在這2處設置斷點進行跟蹤可以看到USB輸入輸出的處理過程:
當中斷發生時調用順序為:stm32f0xx_it.c的
void USB_IRQHandler(void)
{
USB_Istr();
}
usb_dcd_int.c的
void USB_Istr(void)
{
__IO uint16_t wIstr = 0;
wIstr = _GetISTR();