打印
[STM32F1]

USB中断的问题

[复制链接]
1561|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Cjy_JDxy|  楼主 | 2018-3-30 16:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
USB, ST, AC, ck, se
我要做一款产品,用到STM32。
功能就是在电脑和FPGA之间转发数据。
电脑和STM32之间USB通讯,STM32和FPGA之间用串口通讯。
我设想,电脑下发一个数据,进入STM32的USB中断。
我在USB中断里取出该数,通过串口转发给FPGA。
可是USB编程比较复杂,中断程序也复杂。
/*******************************************************************************
* Function Name  : USB_Istr
* Description    : STR events interrupt service routine
* Input          :
* Output         :
* Return         :
*******************************************************************************/
void USB_Istr(void)
{

  wIstr = _GetISTR();

#if (IMR_MSK & ISTR_RESET)
  if (wIstr & ISTR_RESET & wInterrupt_Mask)
  {
    _SetISTR((u16)CLR_RESET);
    Device_Property.Reset();
#ifdef RESET_CALLBACK
    RESET_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_DOVR)
  if (wIstr & ISTR_DOVR & wInterrupt_Mask)
  {
    _SetISTR((u16)CLR_DOVR);

#ifdef DOVR_CALLBACK
    DOVR_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ERR)
  if (wIstr & ISTR_ERR & wInterrupt_Mask)
  {
    _SetISTR((u16)CLR_ERR);

#ifdef ERR_CALLBACK
    ERR_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_WKUP)
  if (wIstr & ISTR_WKUP & wInterrupt_Mask)
  {
    _SetISTR((u16)CLR_WKUP);


    Resume(RESUME_EXTERNAL);
#ifdef WKUP_CALLBACK
    WKUP_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SUSP)
  if (wIstr & ISTR_SUSP & wInterrupt_Mask)
  {

    /* check if SUSPEND is possible */
    if (fSuspendEnabled)
    {
      Suspend();
    }
    else
    {
      /* if not possible then resume after xx ms */
      Resume(RESUME_LATER);
    }
    /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
    _SetISTR((u16)CLR_SUSP);
#ifdef SUSP_CALLBACK
    SUSP_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SOF)
  if (wIstr & ISTR_SOF & wInterrupt_Mask)
  {
    _SetISTR((u16)CLR_SOF);

    bIntPackSOF++;

#ifdef SOF_CALLBACK
    SOF_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ESOF)
  if (wIstr & ISTR_ESOF & wInterrupt_Mask)
  {
    _SetISTR((u16)CLR_ESOF);

    /* resume handling timing is made with ESOFs */
    Resume(RESUME_ESOF); /* request without change of the machine state */
#ifdef ESOF_CALLBACK
    ESOF_Callback();
#endif
  }
#endif

  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_CTR)
  if (wIstr & ISTR_CTR & wInterrupt_Mask)
  {
    /* servicing of the endpoint correct transfer interrupt */
    /* clear of the CTR flag into the sub */
    CTR_LP();
#ifdef CTR_CALLBACK
    CTR_Callback();
#endif
  }
#endif
} /* USB_Istr */
/*
************************************************************************
*º¯ÊýÔ­ÐÍ£ºvoid USB_LP_CAN1_RX0_IRQHandler(void)
*Èë¿Ú²ÎÊý£ºÎÞ
*³ö¿Ú²ÎÊý£ºÎÞ
*º¯Êý¹¦ÄÜ£ºUSBÖжϷþÎñº¯Êý
************************************************************************
*/       
void USB_LP_CAN1_RX0_IRQHandler(void)
{
    USB_Istr();
}


我想问,我进到USB中断里以后,在程序的哪个地方取数呢?
这段程序不好懂。
谢谢!
沙发
Cjy_JDxy|  楼主 | 2018-3-31 09:04 | 只看该作者
谁做过USB中断接收的项目?指点一下。

使用特权

评论回复
板凳
qiangtech| | 2018-3-31 10:59 | 只看该作者
我觉得你可以参考下ST官方的USBD中的VCP虚拟串口的程序。

使用特权

评论回复
地板
Cjy_JDxy|  楼主 | 2018-3-31 11:29 | 只看该作者
qiangtech 发表于 2018-3-31 10:59
我觉得你可以参考下ST官方的USBD中的VCP虚拟串口的程序。

谢谢!  if (wIstr & ISTR_ESOF & wInterrupt_Mask)
  {
    /* clear ESOF flag in ISTR */
    _SetISTR((uint16_t)CLR_ESOF);
   
    if ((_GetFNR()&FNR_RXDP)!=0)
    {
      /* increment ESOF counter */
      esof_counter ++;
      
      /* test if we enter in ESOF more than 3 times with FSUSP =0 and RXDP =1=>> possible missing SUSP flag*/
      if ((esof_counter >3)&&((_GetCNTR()&CNTR_FSUSP)==0))
      {           
        /* this a sequence to apply a force RESET*/
      
        /*Store CNTR value */
        wCNTR = _GetCNTR();
      
        /*Store endpoints registers status */
        for (i=0;i<8;i++) EP = _GetENDPOINT(i);
      
        /*apply FRES */
        wCNTR|=CNTR_FRES;
        _SetCNTR(wCNTR);

        /*clear FRES*/
        wCNTR&=~CNTR_FRES;
        _SetCNTR(wCNTR);
      
        /*poll for RESET flag in ISTR*/
        while((_GetISTR()&ISTR_RESET) == 0);
  
        /* clear RESET flag in ISTR */
        _SetISTR((uint16_t)CLR_RESET);
   
       /*restore Enpoints*/
        for (i=0;i<8;i++)
        _SetENDPOINT(i, EP);
      
        esof_counter = 0;
      }
    }
    else
    {
        esof_counter = 0;
    }
   
    /* resume handling timing is made with ESOFs */
    Resume(RESUME_ESOF); /* request wi
这一段程序是接收数据吗?EP是不是收到的数据?

使用特权

评论回复
5
qiangtech| | 2018-3-31 11:38 | 只看该作者
这段看起来好像是接收到数据后的中断,它需要判断是哪个EP的数据之类的。EP不是收到的数据,EP是ENDPOINT端点。枚举成功后PC就会将数据发送到指定的EP上

使用特权

评论回复
6
Cjy_JDxy|  楼主 | 2018-3-31 11:43 | 只看该作者
qiangtech 发表于 2018-3-31 11:38
这段看起来好像是接收到数据后的中断,它需要判断是哪个EP的数据之类的。EP不是收到的数据,EP是ENDPOINT端 ...

那你知道接收数据那部分代码在哪吗?谢谢!

使用特权

评论回复
7
qiangtech| | 2018-3-31 11:43 | 只看该作者
USB的工作机制比较复杂,如果你急着做这部分,建议你可以参考正点原子的开发指南,里面有章节讲解和移植了USB 的VCP功能的示例代码,你可以参考下。稍作修改应该就可以用了。

使用特权

评论回复
8
Cjy_JDxy|  楼主 | 2018-3-31 12:01 | 只看该作者
qiangtech 发表于 2018-3-31 11:43
USB的工作机制比较复杂,如果你急着做这部分,建议你可以参考正点原子的开发指南,里面有章节讲解和移植了U ...

我有一个例程,是以前工作时用到的。只是程序不是我写的,
那个程序只用到发送,没用接收。现在我就是不知道接收怎么弄。

使用特权

评论回复
9
qiangtech| | 2018-3-31 12:25 | 只看该作者
我的理解是:如果有数据输入,那应该是会进RX中断里,然后判断是哪个EP的数据。一般通信的数据都是在非0的端点上,具体是哪个EP要看程序的设计。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:绿水本无忧因风皱面,青山原不老为雪白头。

553

主题

3530

帖子

19

粉丝