我正在开发一个使用STM32L442KC的项目,我无法检测到何时断开了USB设备模式(USB电缆拔出)。
我能做些什么来检测USB断开?有什么打扰吗?还是我需要检查一下旗子?
更新:
下面是由STM32CubeMX生成的IRQ。它没有HAL_PCD_DisconnectCallback回调,当电缆拔出时不调用HAL_PCD_SuspendCallback。
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
{
uint32_t wInterrupt_Mask = 0;
if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR))
{
/* servicing of the endpoint correct transfer interrupt */
/* clear of the CTR flag into the sub */
PCD_EP_ISR_Handler(hpcd);
}
if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET))
{
__HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
HAL_PCD_ResetCallback(hpcd);
HAL_PCD_SetAddress(hpcd, 0);
}
if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR))
{
__HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
}
if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR))
{
__HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
}
if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP))
{
hpcd->Instance->CNTR &= ~(USB_CNTR_LPMODE);
/*set wInterrupt_Mask global variable*/
wInterrupt_Mask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \
| USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM;
/*Set interrupt mask*/
hpcd->Instance->CNTR = wInterrupt_Mask;
/* enable L1REQ interrupt */
if (hpcd->Init.lpm_enable ==1)
{
wInterrupt_Mask |= USB_CNTR_L1REQM;
/* Enable LPM support and enable ACK answer to LPM request*/
USB_TypeDef *USBx = hpcd->Instance;
hpcd->lpm_active = ENABLE;
hpcd->LPM_State = LPM_L0;
USBx->LPMCSR |= (USB_LPMCSR_LMPEN);
USBx->LPMCSR |= (USB_LPMCSR_LPMACK);
}
if(hpcd->LPM_State == LPM_L1)
{
hpcd->LPM_State = LPM_L0;
HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE);
}
HAL_PCD_ResumeCallback(hpcd);
__HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
}
if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP))
{
/* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
__HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
/* Force low-power mode in the macrocell */
hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0)
{
HAL_PCD_SuspendCallback(hpcd);
}
}
/* Handle LPM Interrupt */
if(__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ))
{
__HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ);
if( hpcd->LPM_State == LPM_L0)
{
/* Force suspend and low-power mode before going to L1 state*/
hpcd->Instance->CNTR |= USB_CNTR_LPMODE;
hpcd->Instance->CNTR |= USB_CNTR_FSUSP;
hpcd->LPM_State = LPM_L1;
hpcd->BESL = (hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >>2 ;
HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE);
}
else
{
HAL_PCD_SuspendCallback(hpcd);
}
}
if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF))
{
__HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
HAL_PCD_SOFCallback(hpcd);
}
if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF))
{
/* clear ESOF flag in ISTR */
__HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
}
}发布于 2017-10-20 08:58:12
在STM32 F7中,您可以在函数void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)、文件usbd_conf.c中检测到断开连接。我希望在L4中也是如此。
发布于 2022-11-19 12:39:55
我不知道您的stm32,但是我使用STM32CubeMX生成代码,我的董事会是"stm32f4",我有一个名为"usb_host.c“的文件。在这个文件中,我有一个函数:
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{
/* USER CODE BEGIN CALL_BACK_1 */
switch(id)
{
case HOST_USER_SELECT_CONFIGURATION:
break;
case HOST_USER_DISCONNECTION:
Appli_state = APPLICATION_DISCONNECT;
break;
case HOST_USER_CLASS_ACTIVE:
printf("READY\n");
Appli_state = APPLICATION_READY;
break;
case HOST_USER_CONNECTION:
Appli_state = APPLICATION_START;
break;
default:
break;
}
/* USER CODE END CALL_BACK_1 */
},我完成了,
如果你想要你自己的回调:
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{
/* USER CODE BEGIN CALL_BACK_1 */
FATFS_USBcallback(phost, id);
/* USER CODE END CALL_BACK_1 */
}在另一份文件中:
void (*__usbChangedCallback)(ApplicationTypeDef) = NULL;
void FATFS_setStateChangedCallback(void (*callback)(ApplicationTypeDef)){
__usbChangedCallback = callback;
}
void FATFS_USBcallback(USBH_HandleTypeDef *phost, uint8_t id){
switch(id){
case HOST_USER_SELECT_CONFIGURATION:
break;
case HOST_USER_DISCONNECTION:
state = APPLICATION_DISCONNECT;
break;
case HOST_USER_CLASS_ACTIVE:
FATFS_PRINTF("APPLICATION_READY\n");
state = APPLICATION_READY;
break;
case HOST_USER_CONNECTION:
FATFS_PRINTF("APPLICATION_START\n");
state = APPLICATION_START;
break;
default:
break;
}
if(__usbChangedCallback != NULL)
__usbChangedCallback(state);
}实现您自己的回调:
void myCallback(ApplicationTypeDef state){
//bla bla bla
}在那之后,做任何你需要做的事:
FATFS_setStateChangedCallback(myCallback);好好享受吧。
https://stackoverflow.com/questions/46836980
复制相似问题