调试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();