有关CH372或CH375的USB通讯的问题解答

版主 你好,在这里请教一个问题: 目前的设计需求是这样:做一个单片机数据采集系统,一方面将数据以文件的形式存入SD卡内,另一方面将将数据与PC机进行USB通讯,PC上做一个上位机程序对数据进行显示,目前我的设计方案是采用一个CH376模块一方面用HOST模式对SD卡读写,一方面来用DEVICE模式来与PC通讯,不知道此方案是否可行?或者还有一些更好的建议吗? 谢谢。。。


CH376在做主机和做设备的时候,是不允许同时使用的,和计算机通信的时候不允许操作SD卡,操作SD卡的时候不允许和计算机通信。


`我用at89s52和ch375与pc机通行,单片机烧的是text.c程序(接口经过修改),pc机运行的是ch372dbg.exe,可以正确的上传和下传数据,可是当pc机运行text.exe程序时老是出现长度错误,请问这是什么原因?是硬件的问题吗?应该如何修改!谢谢,不胜感激!

邮箱:个人信息保护,已隐藏


text.exe 要求下位机把接受到的数据取反,然后回传!


这个我试过了,还是不行。在ch375dbg.exe上可以看到上传的反码。text.exe的原程序一定要在vc5.0或6.0上才能调试吗,其他的可不可以,比如说win-tc等比较原始的平台。

在线等待,谢谢!


win-tc不支持WIN32吧!最好是用VC6.0!


测试通过了! 想用c#开发一个应用程序,不知道有没有可参考的程序?


谁能提供ch375现成的当设备用的电路图及单片机端程序,小弟遇到点问题,想参考一下,拜托了


例子你可以去参考CH372EVT.ZIP里面的程序,原理图建议你去看下CH372DS1,里面有例子程序。


有没有C#的例子程序可供参考啊!


新来的,最近要用到这个芯片,来学习一下,请各位高手多多帮助啊,谢谢啦


请教CH374和PC机的通讯问题: 1) 数据块上传。如果数据块长度取64,上传一个数据块需要2毫秒;如果把数据长度改为63,则传一个数据快 是1毫秒。正常长度应该是64吧? 2) 上传速度太低。采用直接上传模式时,每毫秒只能上传一个数据块,上传速度为64K/S,后改为内部缓冲上传模式(程序如下所述),mDEFAULT_BUFFER_LEN=0x1000。但上传速度还是不变,最高为64.5K/S.据资料介绍理想情况下速度可达到500K/S. 不知问题出在哪,请指教。

1.单片机程序使用 \ CH374 \ PUB\EXAM \ DEVICE \ DEVICE.C void USB_DeviceInterrupt( void ) // USB设备中断服务程序 { 。。。。。。 else if ( s & BIT_IF_TRANSFER ) { // USB传输完成 s = Read374Byte( REG_USB_STATUS ); switch( s & BIT_STAT_PID_ENDP ) { // USB设备中断状态 0x0F case USB_INT_EP2_OUT: // 批量端点下传成功 { UINT8 buf[64]; if ( s & BIT_STAT_TOG_MATCH ) { // 仅同步包 l = Read374Byte( REG_USB_LENGTH ); Read374Block( RAM_ENDP2_RECV, l, buf ); for ( s = 0; s < l; s ++ ) buf[s] ^= 0xFF; // 数据取反由计算机验证 for(s=0;s<64;s++) { upstream[s]=s; } Write374Byte (REG_USB_ENDP2,M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG ); } break; } case USB_INT_EP2_IN: // 批量端点上传成功,未处理 { //本段程序用时34微秒 M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_TRAN_TOG ); tranCtl=1; break; } 。。。。。。 }

void main(void) { 。。。。。。 for(;;) { if(tranCtl==1) { //向CH374写数据耗时330微秒 Write374Block( RAM_ENDP2_TRAN, 63, upstream ); Write374Byte( REG_USB_LENGTH, 63 ); tranCtl=0; } if(USBint==0) { USB_DeviceInterrupt( ); } } }

2、计算机程序使用 \ DEBUG372 \ PC \ CH372UpDown.dsp void CCH372UpDownDlg::OnButton2Up() //端点2上传 { CWinThread * mTrdUp2 = NULL; UpdateData(TRUE); if(!m_open){ MessageBox("请先打开设备!","DEBUG372",MB_OK|MB_ICONSTOP); return; } if(T2UHandle == INVALID_HANDLE_VALUE) { UCHAR DeviceName[128]; memcpy(&DeviceName[0],CH375GetDeviceName(mIndex),sizeof(DeviceName)); T2UHandle = CreateFile( (char *)&DeviceName[0], GENERIC_READ | ERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); // 打开设备 if(T2UHandle == INVALID_HANDLE_VALUE) { MessageBox("无法打开设备!","DEBUG372",MB_OK|MB_ICONSTOP); return; } } if(m_uplen2 > mCH375_PACKET_LENGTH*8 ) { MessageBox("上传长度无效!","DEBUG372",MB_OK); return; } Sleep(10); CH375SetBufUpload(0,1); // 设定内部缓冲上传模式 UpdateData(FALSE); }

每隔15mS读一次数据: void CCH372UpDownDlg::OnTimer(UINT nIDEvent) { UCHAR mBuf[9800]; static int UpCount2,second0,timec=0; CTime theTime; timec++; int pakage=CH375QueryBufUpload(0); if(pakage>0) { ULONG dlen=pakage*64; if(CH375ReadData((ULONG)T2UHandle,&mBuf[0],&dlen)) { theTime = CTime::GetCurrentTime(); UpCount2=UpCount2+dlen; int second=theTime.GetSecond( ); if(second!=second0) { second0=second; char tem[50]=""; memset(&tem,0,sizeof(tem)); sprintf(tem,"Sp: %d /s",UpCount2); ::SetDlgItemText(m_hWnd,IDC_SPEED,tem); UpCount2=0; timec=0; } } } }


1、USB传输以帧为单位,一个帧的时长为1mS,对于批量传输,一帧中可以传输多个数据包 2、CH374的端点2缓冲区是64B,想达到最快速度,每次必须传输以满包64B传输 3、速度与单片机的主频,数据处理复杂度有关,测速度的话,下载CH372EVT.ZIP,下位机参参考\BULK\MCU_C51,上位机直接用\BULK\WIN\BULKTEST.EXE 4、你的这段下位机程序流程有错误,数据是在主程序中上传的话,那么 case USB_INT_EP2_IN: // 批量端点上传成功,未处理 { Write374Byte( REG_USB_ENDP2,M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ^ BIT_EP2_TRAN_TOG ); tranCtl=1; break; } 而主程序中向374写入数据块后增加: Write374Byte( REG_USB_ENDP2,M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) );


请教CH375和AVR单片机通信的问题! 我用的CH375的主机方式,用并口和单片机连接,然后编了一个串口程序来检测CH375的状态,并把数据返回PC机。用CMD_CHECK_EXIST命令来检测,结果串口调试助手返回的数据一直是0xFF,375的时钟,复位等都检查了没问题,请教一下是什么原因。下面是我编的程序: #include #include #include #include "CH375INC.H"

void delay2us( ) { unsigned char i; for ( i = 2; i != 0; i -- ); } /*外部定义的被CH375程序库调用的子程序,向CH375写命令,*/ void xWriteCH375Cmd(unsigned char mCmd) { PORTC|=0X02;/*PC1置高*/ delay2us( );/*至少延时1us*/ PORTC&=0XFD;/*PC1置低*/ PORTC|=0x01;/*A0=1*/ PORTB=mCmd;/*向CH375的并口输出数据*/ DDRB=0xFF;/*并口D0-D7输出*/ PORTD|=0x80;/*同上,RD=1*/ PORTC&=0xFB;/*输出有效写控制信号,CS=0*/ //PORTC|=0X01;/*A0=1*/ PORTD&=0XBF;/*WR=0*/ DDRB=0xFF;/*该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100ns*/ PORTD|=0xC0;/*同上,WR=1,RD=1*/ PORTC|=0x05;/*输出无效的控制信号,完成操作CH375芯片,A0=1,CS=1*/ DDRB=0x00;/*禁止数据输出*/ delay2us( );/*至少延时2US*/ }

/*外部定义的被CH375程序库调用的子程序,向CH375写数据*/ void xWriteCH375Data(unsigned char mData) { PORTC&=0xFE;/*A0=0*/ PORTB=mData;/*向CH375的并口输出数据*/ DDRB=0xFF;/*并口D0-D7输出*/ PORTD|=0x80;/*同上,RD=1*/ PORTC&=0xFA;/*输出有效写控制信号,写CH375芯片的数据端口,A0=0,CS=0*/ PORTD&=0XBF;/*WR=0*/ DDRB=0xFF;/*该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100ns*/ PORTD|=0xC0;/*同上,WR=1,RD=1*/ PORTC|=0x04;/*输出无效的控制信号,完成操作CH375芯片,CS=1*/ //PORTC&=0XFE;/*A0=0*/ DDRB=0x00;/*禁止数据输出*/ delay2us( );/*至少延时2us*/ }

/*外部定义的被CH375程序库调用的子程序,从CH375读数据,*/ unsigned char xReadCH375Data(void) { unsigned char mData; delay2us( );/*至少延时1.2us*/ DDRB=0x00;/*数据输入*/ PORTD|=0X40;/*WR=1*/ PORTC&=0xFA;/*输出有效读控制信号,读CH375的数据端口,A0=0,CS=0*/ PORTD&=0x7F;/*同上,RD=0*/ DDRB=0x00;/*该操作无意义,仅作延时,CH375要求读写脉冲宽度大于100ns*/ mData=PINB;/*从CH375的并口PB输入数据*/ //PORTC&=0xFE;/*A0=0*/ PORTD|=0xC0;/*WR=1,RD=1*/ PORTC|=0X04;/*CS=1*/ return(mData); }

//单片机串口初始化 void USART_Init(void) { UCSRA=0x02;/*倍速*/ UCSRB=0x18;/*允许接收和发送*/ UCSRC=0x86;/*8位数据*/ UBRRH=0x00; UBRRL=0x08;/*设置波特率,115.2K*/ }

void USART_Transmit( unsigned char data ) { /* 等待发送缓冲器为空 */ while ( !( UCSRA & (1</* 将数据放入缓冲器,发送数据 */ UDR = data; }

unsigned char USART_Receive( void ) { /* 等待接收数据*/ while ( !(UCSRA & (1</* 从缓冲器中获取并返回数据*/ return UDR; }

void CH375_PORT_INIT( ) /* 由于使用通用I/O模块并口读写时序,所以进行初始化 */ { unsigned char i, k; //unsigned char RD_Data;

DDRB=0x00; /* 设置8位并口为输入 */ DDRC=0x07; /*设置CS、A0为输出*/ DDRD=0xC0; /* 设置WR,RD为输出,设置INT#为输入 */ PORTC|=0x04; /* 设置CS默认为高电平 */ PORTD|=0xE0; /*设置WR,RD,INT默认为高电平*/ }

/*利用PC机串口来检测CH375是否正常工作*/ void CH375_TEST( ) { unsigned char temp; unsigned char RD_Data; DDRD=0x02;/*TXD,RXD引脚PD1,PD2分别置为输出和输入,*/ while(1) { /*等待接收数据*/ temp=USART_Receive(); /*把接收到的数据写到CH375里面*/ xWriteCH375Cmd( CMD_CHECK_EXIST ); xWriteCH375Data(temp); /*从CH375读数据*/ temp=~temp; RD_Data=xReadCH375Data(); /*发送接收到得数据*/ USART_Transmit(RD_Data); } }

main( ) { delay2us( ); CH375_PORT_INIT( ); USART_Init( ); CH375_TEST( ); }


1、接口程序写的有点乱,参考下面的写,不要随意增加额外的代码 /* 单片机的引脚 CH375芯片的引脚 PINB.4 INT# PORTB.3 A0 PORTB.2 CS# PORTB.1 WR# PORTB.0 RD# PORTA(8位端口) D7-D0 */

void CH375_PORT_INIT( ) /* 由于使用通用I/O模块并口读写时序,所以进行初始化 */ { DDRA = 0x00; /* 设置8位并口为输入 */ PORTB = 0x07; /* 设置CS,WR,RD默认为高电平 */ DDRB = 0x0F; /* 设置CS,WR,RD,A0为输出,设置INT#为输入 */ }

void xWriteCH375Cmd( UINT8 mCmd ) { PORTB |= 0x08; /* 输出A0=1 */ PORTA = mCmd; /* 向CH375的并口输出数据 */ DDRA = 0xFF; /* 并口D0-D7输出 */ PORTB &= 0xF9; /* 输出有效写控制信号, CS=0; WR=0 */ DDRA = 0xFF; /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于60nS */ PORTB |= 0x07; /* 输出无效的控制信号, CS=1; WR=1; */ DDRA = 0x00; /* 禁止数据输出 */ PORTB &= 0xF7; /* 输出A0=0; 可选操作 */ mDelay2uS( ); /* 至少延时1.5uS */ }

void xWriteCH375Data( UINT8 mData ) { PORTA = mData; /* 向CH375的并口输出数据 */ DDRA = 0xFF; /* 并口D0-D7输出 */ PORTB &= 0xF1; /* 输出有效写控制信号, CS=0; WR=0; */ DDRA = 0xFF; /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于60nS */ PORTB |= 0x07; /* 输出无效的控制信号, CS=1; WR=1; */ DDRA = 0x00; /* 禁止数据输出 */ mDelay1uS( ); /* 至少延时0.6uS */ }

UINT8 xReadCH375Data( void ) { UINT8 mData;

mDelay1uS( ); /* 至少延时0.6uS */ DDRA = 0x00; /* 数据输入 */ PORTB &= 0xF2; /* 输出有效读控制信号, CS=0; RD=0; */ DDRA = 0x00; /* 该操作无意义,仅作延时,CH375要求读写脉冲宽度大于60nS */ mData = PINA; /* 从CH375的并口PA输入数据 */ PORTB |= 0x07; /* 输出无效的控制信号, CS=1; RD=1; */ return( mData ); } 2、单片机上电后,需要延时100mS,等375复位完成后才能操作 3、测试命令的过程繁琐了,直接写入常数测试,把结果从串口输出 xWriteCH375Cmd( CMD_CHECK_EXIST ); xWriteCH375Data( 0x55 ); dat = xReadCH375Data(); 把dat从串口发出去


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