ch32vct6高速usb模拟串口,数据传输比较慢

使用EVT\EXAM\USB\USBHS\DEVICE\SimulateCDC-HID这个例子来修改,上传速度只能达到19MB/s,是不是我程序修改有问题?

/*********************************************************************
?*?@fn??????UART2_DataRx_Deal
?*
?*?@brief???Uart2?data?receiving?processing
?*
?*?@return??none
?*/
void?UART2_DataRx_Deal(?void?)
{
????uint16_t?temp16;
????uint32_t?remain_len;
????uint16_t?packlen;

//????/*?Serial?port?1?data?DMA?receive?processing?*/
//????NVIC_DisableIRQ(?USBHS_IRQn?);
//????NVIC_DisableIRQ(?USBHS_IRQn?);
//????UARTx_Rx_DMACurCount?=?DEF_UART2_RX_DMA_CH->CNTR;
//????if(?UARTx_Rx_DMALastCount?!=?UARTx_Rx_DMACurCount?)
//????{
//????????if(?UARTx_Rx_DMALastCount?>?UARTx_Rx_DMACurCount?)
//????????{
//????????????temp16?=?UARTx_Rx_DMALastCount?-?UARTx_Rx_DMACurCount;
//????????}
//????????else
//????????{
//????????????temp16?=?DEF_UARTx_RX_BUF_LEN?-?UARTx_Rx_DMACurCount;
//????????????temp16?+=?UARTx_Rx_DMALastCount;
//????????}
//????????UARTx_Rx_DMALastCount?=?UARTx_Rx_DMACurCount;
//????????if(?(?Uart.Rx_RemainLen?+?temp16?)?>?DEF_UARTx_RX_BUF_LEN?)
//????????{
//????????????/*?Overflow?handling?*/
//????????????/*?Save?frame?error?status?*/
//????????????DUG_PRINTF("U0_O:%08lx\n",(uint32_t)Uart.Rx_RemainLen);
//????????}
//????????else
//????????{
//????????????Uart.Rx_RemainLen?+=?temp16;
//????????}
//
//????????/*?Setting?reception?status?*/
//????????Uart.Rx_TimeOut?=?0x00;
//????}
//????NVIC_EnableIRQ(?USBHS_IRQn?);

????/*****************************************************************/
????/*?Serial?port?1?data?processing?via?USB?upload?and?reception?*/
//????if(?Uart.Rx_RemainLen?)
????{
????????if(?Uart.USB_Up_IngFlag?==?0?)
????????{
????????????/*?Calculate?the?length?of?this?upload?*/
????????????remain_len?=?Uart.Rx_RemainLen;
????????????packlen?=?0x00;
????????????if(?remain_len?>=?DEF_USBD_HS_PACK_SIZE?)
????????????{
????????????????packlen?=?DEF_USBD_HS_PACK_SIZE;
????????????}
????????????else
????????????{
????????????????if(?Uart.Rx_TimeOut?>=?Uart.Rx_TimeOutMax?)
????????????????{
????????????????????packlen?=?remain_len;
????????????????}
????????????}
????????????if(?packlen?>?(?DEF_UARTx_RX_BUF_LEN?-?Uart.Rx_DealPtr?)?)
????????????{
????????????????packlen?=?(?DEF_UARTx_RX_BUF_LEN?-?Uart.Rx_DealPtr?);
????????????}

????????????/*?Upload?serial?data?via?usb?*/
????????????if(?packlen=512?)//每次固定发送512字节
????????????{
????????????????NVIC_DisableIRQ(?USBHS_IRQn?);
????????????????NVIC_DisableIRQ(?USBHS_IRQn?);
????????????????Uart.USB_Up_IngFlag?=?0x01;
????????????????Uart.USB_Up_TimeOut?=?0x00;
????????????????USBHSD->UEP2_TX_DMA?=?(uint32_t)(uint8_t?*)&UART2_Rx_Buf[?0?];
????????????????USBHSD->UEP2_TX_LEN??=?packlen;
????????????????USBHSD->UEP2_TX_CTRL?&=?~USBHS_UEP_T_RES_MASK;
????????????????USBHSD->UEP2_TX_CTRL?|=?USBHS_UEP_T_RES_ACK;
????????????????NVIC_EnableIRQ(?USBHS_IRQn?);

????????????????/*?Calculate?the?variables?of?interest?*/
????????????????Uart.Rx_RemainLen?-=?packlen;
????????????????Uart.Rx_DealPtr?+=?packlen;
????????????????if(?Uart.Rx_DealPtr?>=?DEF_UARTx_RX_BUF_LEN?)
????????????????{
????????????????????Uart.Rx_DealPtr?=?0x00;
????????????????}

????????????????/*?Start?0-length?packet?timeout?timer?*/
????????????????if(?packlen?==?DEF_USBD_HS_PACK_SIZE?)
????????????????{
????????????????????Uart.USB_Up_Pack0_Flag?=?0x01;
????????????????}
????????????}
????????}
????????else
????????{
????????????/*?Set?the?upload?success?flag?directly?if?the?upload?is?not?successful?after?the?timeout?*/
????????????if(?Uart.USB_Up_TimeOut?>=?DEF_UARTx_USB_UP_TIMEOUT?)
????????????{
????????????????Uart.USB_Up_IngFlag?=?0x00;
????????????????USBHS_Endp_Busy[?DEF_UEP2?]?=?0;
????????????}
????????}
????}

????/*****************************************************************/
????/*?Determine?if?a?0-length?packet?needs?to?be?uploaded?(required?for?CDC?mode)?*/
//????if(?Uart.USB_Up_Pack0_Flag?)
//????{
//????????if(?Uart.USB_Up_IngFlag?==?0?)
//????????{
//????????????if(?Uart.USB_Up_TimeOut?>=?(?DEF_UARTx_RX_TIMEOUT?*?20?)?)
//????????????{
//????????????????NVIC_DisableIRQ(?USBHS_IRQn?);
//????????????????NVIC_DisableIRQ(?USBHS_IRQn?);
//????????????????Uart.USB_Up_IngFlag?=?0x01;
//????????????????Uart.USB_Up_TimeOut?=?0x00;
//????????????????USBHSD->UEP2_TX_LEN??=?0x00;
//????????????????USBHSD->UEP2_TX_CTRL?&=?~USBHS_UEP_T_RES_MASK;
//????????????????USBHSD->UEP2_TX_CTRL?|=?USBHS_UEP_T_RES_ACK;
//????????????????Uart.USB_Up_IngFlag?=?0;
//????????????????NVIC_EnableIRQ(?USBHS_IRQn?);
//????????????????Uart.USB_Up_Pack0_Flag?=?0x00;
//????????????}
//????????}
//????}
}


void UART2_DataRx_Deal( void )
{
    uint16_t temp16;
    uint32_t remain_len;
    uint16_t packlen;

//    /* Serial port 1 data DMA receive processing */
//    NVIC_DisableIRQ( USBHS_IRQn );
//    NVIC_DisableIRQ( USBHS_IRQn );
//    UARTx_Rx_DMACurCount = DEF_UART2_RX_DMA_CH->CNTR;
//    if( UARTx_Rx_DMALastCount != UARTx_Rx_DMACurCount )
//    {
//        if( UARTx_Rx_DMALastCount > UARTx_Rx_DMACurCount )
//        {
//            temp16 = UARTx_Rx_DMALastCount - UARTx_Rx_DMACurCount;
//        }
//        else
//        {
//            temp16 = DEF_UARTx_RX_BUF_LEN - UARTx_Rx_DMACurCount;
//            temp16 += UARTx_Rx_DMALastCount;
//        }
//        UARTx_Rx_DMALastCount = UARTx_Rx_DMACurCount;
//        if( ( Uart.Rx_RemainLen + temp16 ) > DEF_UARTx_RX_BUF_LEN )
//        {
//            /* Overflow handling */
//            /* Save frame error status */
//            DUG_PRINTF("U0_O:%08lx\n",(uint32_t)Uart.Rx_RemainLen);
//        }
//        else
//        {
//            Uart.Rx_RemainLen += temp16;
//        }
//
//        /* Setting reception status */
//        Uart.Rx_TimeOut = 0x00;
//    }
//    NVIC_EnableIRQ( USBHS_IRQn );

    /*****************************************************************/
    /* Serial port 1 data processing via USB upload and reception */
//    if( Uart.Rx_RemainLen )
    {
        if( Uart.USB_Up_IngFlag == 0 )
        {
            /* Calculate the length of this upload */
            remain_len = Uart.Rx_RemainLen;
            packlen = 0x00;
            if( remain_len >= DEF_USBD_HS_PACK_SIZE )
            {
                packlen = DEF_USBD_HS_PACK_SIZE;
            }
            else
            {
                if( Uart.Rx_TimeOut >= Uart.Rx_TimeOutMax )
                {
                    packlen = remain_len;
                }
            }
            if( packlen > ( DEF_UARTx_RX_BUF_LEN - Uart.Rx_DealPtr ) )
            {
                packlen = ( DEF_UARTx_RX_BUF_LEN - Uart.Rx_DealPtr );
            }

            /* Upload serial data via usb */
            if( packlen=512 )//每次固定发送512字节
            {
                NVIC_DisableIRQ( USBHS_IRQn );
                NVIC_DisableIRQ( USBHS_IRQn );
                Uart.USB_Up_IngFlag = 0x01;
                Uart.USB_Up_TimeOut = 0x00;
                USBHSD->UEP2_TX_DMA = (uint32_t)(uint8_t *)&UART2_Rx_Buf[ 0 ];
                USBHSD->UEP2_TX_LEN  = packlen;
                USBHSD->UEP2_TX_CTRL &= ~USBHS_UEP_T_RES_MASK;
                USBHSD->UEP2_TX_CTRL |= USBHS_UEP_T_RES_ACK;
                NVIC_EnableIRQ( USBHS_IRQn );

                /* Calculate the variables of interest */
                Uart.Rx_RemainLen -= packlen;
                Uart.Rx_DealPtr += packlen;
                if( Uart.Rx_DealPtr >= DEF_UARTx_RX_BUF_LEN )
                {
                    Uart.Rx_DealPtr = 0x00;
                }

                /* Start 0-length packet timeout timer */
                if( packlen == DEF_USBD_HS_PACK_SIZE )
                {
                    Uart.USB_Up_Pack0_Flag = 0x01;
                }
            }
        }
        else
        {
            /* Set the upload success flag directly if the upload is not successful after the timeout */
            if( Uart.USB_Up_TimeOut >= DEF_UARTx_USB_UP_TIMEOUT )
            {
                Uart.USB_Up_IngFlag = 0x00;
                USBHS_Endp_Busy[ DEF_UEP2 ] = 0;
            }
        }
    }

    /*****************************************************************/
    /* Determine if a 0-length packet needs to be uploaded (required for CDC mode) */
//    if( Uart.USB_Up_Pack0_Flag )
//    {
//        if( Uart.USB_Up_IngFlag == 0 )
//        {
//            if( Uart.USB_Up_TimeOut >= ( DEF_UARTx_RX_TIMEOUT * 20 ) )
//            {
//                NVIC_DisableIRQ( USBHS_IRQn );
//                NVIC_DisableIRQ( USBHS_IRQn );
//                Uart.USB_Up_IngFlag = 0x01;
//                Uart.USB_Up_TimeOut = 0x00;
//                USBHSD->UEP2_TX_LEN  = 0x00;
//                USBHSD->UEP2_TX_CTRL &= ~USBHS_UEP_T_RES_MASK;
//                USBHSD->UEP2_TX_CTRL |= USBHS_UEP_T_RES_ACK;
//                Uart.USB_Up_IngFlag = 0;
//                NVIC_EnableIRQ( USBHS_IRQn );
//                Uart.USB_Up_Pack0_Flag = 0x00;
//            }
//        }
//    }
}



您好,CDC设备向PC发送数据只需要置len长度、要发送的数据以及端点状态即可。测试过程中尽量避免出现数据拷贝/搬运/打印的过程,建议创建一个固定的buff,每次发送字节数按USB端点最大字节数。数据发送期间不要有其他中断或其他程序影响。其次上位机或驱动获取IN包的时间间隔也是影响测试速率的一大因素。


张工你好我用的台式机测试换过几根USB数据线,上传数据最大只能到 22.5MB/s 跟论坛里的45MB/s相差还是比较大,修改的程序:

int main(void)
{
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    	
    printf("SystemClk:%d\r\n",SystemCoreClock);
    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
    printf( "Simulate USB-CDC/HID Device running on USBHS Controller\r\n" );
    RCC_Configuration( );

    /* Tim2 init */
//    TIM2_Init( );

    /* Usart1 init */
    UART2_Init( 1, DEF_UARTx_BAUDRATE, DEF_UARTx_STOPBIT, DEF_UARTx_PARITY );

    /* USB20 device init */
    USBHS_RCC_Init( );
    USBHS_Device_Init( ENABLE );

    while(1)
    {
        UART2_DataRx_Deal( );
//        UART2_DataTx_Deal( );
    }
}
void UART2_DataRx_Deal( void )
{

    if( Uart.USB_Up_IngFlag == 0 )
    {


        Uart.USB_Up_IngFlag = 0x01;
        Uart.USB_Up_TimeOut = 0x00;
        USBHSD->UEP2_TX_DMA = (uint32_t)(uint8_t *)&UART2_Rx_Buf[0];//(uint32_t)(uint8_t *)&UART2_Rx_Buf[ Uart.Rx_DealPtr ];
        USBHSD->UEP2_TX_LEN  = 512;
        USBHSD->UEP2_TX_CTRL &= ~USBHS_UEP_T_RES_MASK;
        USBHSD->UEP2_TX_CTRL |= USBHS_UEP_T_RES_ACK;


    }

}

这个程序只用来测试上传了,没有其他功能,是不是还要修改其他地方?

image.png






你好,电脑发送OUT包是固定时间间隔,当MCU代码运行速度不够快时,会回复NAK,从而浪费一次传输时间,而且还需要回复一包PING,如下所示image.png

所以会出现速度差了一半的情况,正常跑满的抓包如下

image.png

解决办法是提高MCU主频到144M,提高代码优化等级(MRS默认是高的),目的是加快代码的运行速度,清除USB相关标志位,回复ACK。

如果仍有问题,可以将代码和测试软件发到邮箱zc@wch.cn


只有登录才能回复,可以选择微信账号登录