⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch375.txt

📁 单片机处理USB接口手柄程序 可用于USB通信实现
💻 TXT
📖 第 1 页 / 共 2 页
字号:
    TR1 = 1 ;
    TI = 1 ;
    EX0 = 1 ;
    EA = 0 ;
}

void CH375_WR_CMD_PORT( unsigned char cmd ) /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */
{  
    delay2us() ;
    CH375_CMD_PORT = cmd ;
    delay2us() ;
}

void CH375_WR_DAT_PORT( unsigned char dat ) /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */
{  
    CH375_DAT_PORT = dat ;
    delay1us() ;                                 /* 因为MCS51单片机较慢所以实际上无需延时 */
}

unsigned char CH375_RD_DAT_PORT()           /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */
{  
    delay1us() ;  /* 因为MCS51单片机较慢所以实际上无需延时 */
    return( CH375_DAT_PORT ) ;
}


bit set_usb_mode( unsigned char mode ) /* 设置CH37X的工作模式 */
{  
    unsigned char i ;
    CH375_WR_CMD_PORT( CMD_SET_USB_MODE ) ;
    CH375_WR_DAT_PORT( mode ) ;
    endp6_mode = endp7_mode = 0x80 ;  /* 主机端复位USB数据同步标志 */
    for( i=0 ; i!=100 ; i++ )    /* 等待设置模式操作完成,不超过30uS */
    { 
        if ( CH375_RD_DAT_PORT() == CMD_RET_SUCCESS ) 
            return( TURE );  /* 成功 */
    }
    return( FALSE );  /* CH375出错,例如芯片型号错或者处于串口方式或者不支持 */
}

void set_freq( void )
{   
    CH375_WR_CMD_PORT( CMD_SET_USB_SPEED ) ; 
    CH375_WR_DAT_PORT( 0x02 ) ; 
}

/* 数据同步 */
/* USB的数据同步通过切换DATA0和DATA1实现: 在设备端, CH372/CH375可以自动切换;
   在主机端, 必须由SET_ENDP6和SET_ENDP7命令控制CH375切换DATA0与DATA1.
   主机端的程序处理方法是为SET_ENDP6和SET_ENDP7分别提供一个全局变量,
   初始值均为80H, 每执行一次成功事务后将位6取反, 每执行一次失败事务后将其复位为80H. */

void toggle_recv( void ) /* 主机接收成功后,切换DATA0和DATA1实现数据同步 */
{  
    CH375_WR_CMD_PORT( CMD_SET_ENDP6 ) ;
    CH375_WR_DAT_PORT( endp6_mode ); 
    endp6_mode ^= 0x40 ;
    delay2us() ;
}

unsigned char rd_usb_data( unsigned char *buf ) reentrant /* 从CH375读出数据块 */
{
    unsigned char i , len ;
    CH375_WR_CMD_PORT( CMD_RD_USB_DATA ) ;  /* 从CH375的端点缓冲区读取接收到的数据 */
    len = CH375_RD_DAT_PORT() ;  /* 后续数据长度 */
    for ( i=0 ; i!=len ; i++ ) 
        *buf++=CH375_RD_DAT_PORT() ;
    return( len );
}

void issue_token( unsigned char endp_and_pid )  /* 执行USB事务 */
{  
    CH375_WR_CMD_PORT( CMD_ISSUE_TOKEN ) ;
    CH375_WR_DAT_PORT( endp_and_pid ) ;  /* 高4位目的端点号, 低4位令牌PID */
}

void intt0() interrupt 0
{   
    CH375_WR_CMD_PORT( CMD_GET_STATUS ) ;  /* 产生操作完成中断, 获取中断状态 */
    if( CH375_RD_DAT_PORT() != USB_INT_SUCCESS )
    {   
        CH375_WR_CMD_PORT( CMD_CLR_STALL ) ;
        CH375_WR_DAT_PORT( 0x81 ) ;  /* 如果设备端不是CH37X芯片,那么需要修改端点号 */
        endp6_mode = 0x80 ;
        endp7_mode = 0x80 ;
        toggle_recv() ;
        issue_token( ( endp_int << 4 ) | DEF_USB_PID_IN ) ;//发送从中断端点读数据的令牌
    }
    else 
    {   
        if ( rd_usb_data( USB_Data.data_buf ) != 8 )    //游戏手柄的数据长度为8个字节,数据长度不符,返回
            return ;
        else
            flag_output = 1 ;
        toggle_recv() ;
        issue_token( ( endp_int << 4 ) | DEF_USB_PID_IN ) ;//发送从中断端点读数据的令牌
    }
}

unsigned char wait_interrupt( void ) /* 主机端等待操作完成, 返回操作状态 */
{  
    while( CH375_INT_WIRE ) ;  /* 查询等待CH375操作完成中断(INT#低电平) */
    CH375_WR_CMD_PORT( CMD_GET_STATUS ) ;  /* 产生操作完成中断, 获取中断状态 */
    return( CH375_RD_DAT_PORT() ) ;
}


void get_int_in( void )
{
    endp6_mode = 0x80 ;
    toggle_recv() ;
    issue_token( ( endp_int << 4 ) | DEF_USB_PID_IN ) ;//status=wait_interrupt();
}
void reset_device() /* USB规范中未要求在USB设备插入后必须复位该设备,但是计算机的WINDOWS总是这样做,所以有些USB设备也要求在插入后必须先复位才能工作 */
{   
    set_usb_mode( 7 ) ;  /* 复位USB设备,CH375向USB信号线的D+和D-输出低电平 */
    delayms(10);
    set_usb_mode( 6 ) ;  /* 结束复位 */
    while ( wait_interrupt() != USB_INT_CONNECT ) ;  /* 等待复位之后的设备端再次连接上来 */

}

/* CH375初始化子程序 */
void CH375_Init( void )/* 测试CH375是否正常工作 */
{
    unsigned char i , k ;
    unsigned char RD_Data ;
    while( 1 )
    {
        for( k=100 ; k!=0 ; k-- )
        {
            CH375_WR_CMD_PORT( CMD_CHECK_EXIST );       /* 测试CH375是否正常工作 */

            i = 0x5A ;
            CH375_WR_DAT_PORT( i ) ;                    /* 写入测试数据 */
            i = ~i ;                                    /* 返回数据应该是测试数据取反 */
            RD_Data = CH375_RD_DAT_PORT() ;
            if( RD_Data != i )                          /* CH375不正常 */
            {
                for( i=5 ; i!=0 ; i-- )
                    CH375_WR_CMD_PORT( CMD_RESET_ALL ) ; /* 多次重复发命令,执行硬件复位 */
                delayms( 50 ) ;                             /* 延时50ms */
            }
            else
                break ;
        }
        if( set_usb_mode( 6 ) == TURE )
            break ;
    }
}

bit set_config( void )
{
    CH375_Init() ;                                  /*初始话ch375,并检测是否正常运行*/
    while( wait_interrupt() != USB_INT_CONNECT )    /*等待设备连接上来*/
        reset_device() ;                            /* 复位设备 */
    set_freq() ;                                    /*游戏手柄为低速设备,设置为低速工作方式*/
    CH375_WR_CMD_PORT( CMD_AUTO_SETUP ) ;           /*自动配置游戏手柄*/
    if( wait_interrupt() == USB_INT_SUCCESS )
        return( TURE );
    else
        return( FALSE ) ;
}





void main( void ) 
{
    mInitSTDIO() ;                                      /*初始化串口,全局中断关*/

    while( 1 )
    {   
        while( set_config() != TURE ) ;
        light = 0x00 ;
        EA=1;                                           //打开中断,从中断端点接收数据
        get_int_in();                                   //发送从中断端点读数据的令牌
        while(1)
        {   
            if( flag_output == 1 )
            {
                flag_output = 0 ;
                
            }
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -