USB做主机获取125us sof间隔方法

    当MCU作为USB主机获取125微秒的SOF(Start Of Frame)间隔时,其主要作用是为高速(High-Speed)USB通信提供一个精确的时间基准和同步信号。这个基准主要用于保证实时性数据的同步传输、精准的带宽控制以及防止设备进入休眠状态。下表总结了它的几个核心应用场景:

应用场景核心目的关键机制典型应用
精确的时间同步 让多个USB设备或MCU内部任务基于统一时钟工作 125µs SOF信号作为高精度“心跳” 多声道音频同步采集/播放、多传感器数据融合
实时控制与定时 实现微秒级的精确周期性任务触发 利用SOF中断作为稳定的定时器源 电机控制、高频数据采集、实时控制系统
功耗管理(防止挂起) 维持USB总线活跃,防止设备因无通信进入低功耗挂起状态 主机定期发送SOF包(即使无数据传输) 需要随时唤醒的设备(如HID)、维持长连接的低功耗设备
传输调度与带宽控制 确保时间敏感型数据传输的实时性 主机在一个微帧(125µs)内规划并完成所有事务 USB音频(同步传输)、视频(同步/批量传输)
调试与时间标记 为总线事件提供精确的时间戳,便于分析 每个SOF包携带一个11位的帧编号,可用于标记事件发生的时刻 USB协议分析、系统调试、性能优化

     USBHOST主机的时基处理采取的是定时器125us区计时适配中断端点的binterval轮询,但是125us定时器计时开始时,与USB SOF包同步慢,有时候客户需要传输调度与带宽控制(此次传输时间大于下一个sof包的时间此次传输会被控制器放弃)。主机控制器可以在sof开始的时候然后做标记,开始做125us内会打断USB传输的操作,或者安排几次端点轮循访问。最大限度利用USB带宽并防止总线被打断。

  方法一:开启USB SOF中断

   配置:

void USBHS_Host_Init( FunctionalState sta )
{
    if( sta )
    {
        /* Reset USB module */
        USBHSH->CONTROL = USBHS_UC_CLR_ALL | USBHS_UC_RESET_SIE;
        Delay_Us( 10 );
        USBHSH->CONTROL = 0;
       
        /* Initialize USB host configuration */
        USBHSH->CONTROL = USBHS_UC_HOST_MODE | USBHS_UC_SPEED_HIGH | USBHS_UC_INT_BUSY | USBHS_UC_DMA_EN;
        USBHSH->HOST_EP_CONFIG = USBHS_UH_EP_TX_EN | USBHS_UH_EP_RX_EN;
        USBHSH->HOST_RX_DMA = (uint32_t)USBHS_RX_Buf;
        USBHSH->HOST_TX_DMA = (uint32_t)USBHS_TX_Buf;
        USBHSH->HOST_CTRL = USBHS_UH_PHY_SUSPENDM;    
        USBHSH->HOST_RX_MAX_LEN = USBHS_MAX_PACKET_SIZE;
        USBHSD->INT_EN = USBHS_UIE_SOF_ACT;
        NVIC_EnableIRQ( USBHS_IRQn );
    }
    else
    {
        USBHSH->CONTROL = USBHS_UC_CLR_ALL | USBHS_UC_RESET_SIE;
        Delay_Us( 10 );
        USBHSH->CONTROL = 0;
    }
}
void USBHS_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USBHS_IRQHandler( void )
{
    uint8_t  intflag, intst;
    static uint16_t len;

    intflag = USBHSD->INT_FG;
    intst = USBHSD->INT_ST;
    if( intflag & USBHS_UIF_HST_SOF )
    {
        len++;
       USBHSD->INT_FG = USBHS_UIF_HST_SOF;
        if(len==8000)
        {
        len=0;
        printf("1stimeout\r\n");
        }


    }

 USBHSD->INT_FG = intflag;
}

image

方法二:使用USB_FRAME_NO寄存器,非中断模式

image

image

 

 

    while( 1 )
    {
        USBH_MainDeal( );
        // if(  RootHubDev[0].bStatus == ROOT_DEV_CONNECTED)
        // {
            //    printf("1stimeout\r\n");
           USB_FRAME_NO= (USBHSH->FRAME_NO>>13)&0x07;
          if(LAST_USB_FRAME_NO-USB_FRAME_NO)
          {
              cunt++;
              if(cunt==8000)
              {
                   printf("1stimeout%d\r\n",(int8_t)(USB_FRAME_NO-LAST_USB_FRAME_NO));

                   cunt=0;
              }
          }
           LAST_USB_FRAME_NO=USB_FRAME_NO;
        // }
    }
}
posted @ 2026-02-05 13:25  WCH_CH32  阅读(98)  评论(0)    收藏  举报