📄 ch375.txt
字号:
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 + -