CH375和CH372常见问题的解决[讨论]

/* CH375中断服务程序,使用寄存器组1 */ void mCh375Interrupt( void ) //interrupt 0 using 1 { unsigned char InterruptStatus; unsigned char i, length; //unsigned char data buffer[ 64 ]; unsigned char buffer[ 64 ]; unsigned char Lenth[ 60 ]; //a++; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 获取中断状态并取消中断请求 */ InterruptStatus = CH375_RD_DAT_PORT( ); /* 获取中断状态 */ switch ( InterruptStatus ) { /* 分析中断状态处理 */ case USB_INT_EP2_OUT: { /* 批量端点下传成功 */ CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 */ CH375_RD_DAT_PORT( ); length = RD_DATA; /* 首先读取后续数据长度 */ for ( i = 0; i < length; i ++ ) { CH375_RD_DAT_PORT( ); buffer[ i ] = RD_DATA; /* 接收数据包 */ } CH375_WR_CMD_PORT( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ CH375_WR_DAT_PORT( length ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ for ( i = 0; i { buffer[ i ] = ~buffer[ i ] ; CH375_WR_DAT_PORT( buffer[ i ] ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */ } break; } case USB_INT_EP2_IN: { /* 批量数据发送成功 */ CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ PTCD_PTCD5 = 0; break; } default: { /* 其它中断,未用到,解锁后退出即可 */ CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ break; } } }

void main(void) {

MCUinit(); port_init(); Delay50ms( ); /* 延时等待CH375初始化完成,如果单片机由CH375提供复位信号则不必延时 */ CH375_Init( ); /* 初始化CH375 */ while ( 1 ) /* 以下指令开始工作循环,等待PC机命令进行操作 */ { if(!CH375_INT) { mCh375Interrupt(); } } }


void mCh375Interrupt(void ) //interrupt 0 using 1 { unsigned char InterruptStatus; unsigned char i, length; // unsigned char data buffer[ 64 ]; unsigned char buffer[ 64 ]; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 获取中断状态并取消中断请求 */ InterruptStatus = CH375_RD_DAT_PORT( ); /* 获取中断状态 */ switch ( InterruptStatus ) { /* 分析中断状态处理 */ case USB_INT_EP2_OUT: { /* 批量端点下传成功 */ CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 */ length = CH375_RD_DAT_PORT( ); /* 首先读取后续数据长度 */ DataLong = length; for ( i = 0; i < length; i ++ ) buffer[ i ] = CH375_RD_DAT_PORT( ); /* 接收数据包 */ /* 测试数据正确性,将接收到的命令包数据取反后返回给PC机 */ CH375_WR_CMD_PORT( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ CH375_WR_DAT_PORT( length ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ for ( i = 0; i < length; i ++ ) CH375_WR_DAT_PORT( ~ buffer[ i ] ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */ break; } case USB_INT_EP2_IN: { /* 批量数据发送成功 */ CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ break; } default: { /* 其它中断,未用到,解锁后退出即可 */ CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ break; } } }

void main(void) {

unsigned char Lenth[64] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a}; MCUinit(); port_init(); Delay50ms( ); /* 延时等待CH375初始化完成,如果单片机由CH375提供复位信号则不必延时 */ CH375_Init( ); /* 初始化CH375 */ //EA = 1; /* 允许中断 */ //mCh375Interrupt(); while ( 1 ) /* 以下指令开始工作循环,等待PC机命令进行操作 */ { b++; if(!CH375_INT) { mCh375Interrupt(); } } }


这个简洁点

原来是没有把读数据的函数加进去了。用TEST文件夹的程序试了,可以了

现在有个这样的情况。。。我把数据长度显示出来,DataLong = length;

数据的长度到了48字节之后,就一直显示48

曾经试过发64个字节,长度就是一直显示0xfd 但是通过DEBUG372收到的数据是64个,是UP显示64 端点2上传框框,哪里的长度一直都是灰色的64??

数据长度是不是有问题啊???? 还有端点1上传那个框框有什么用的啊???


使用DEBUG372调试,如果你接收的数据和你发送的数据长度相等,并且是按位取反,则说明传输没有问题, 不知道你用什么显示数据长度,有没有单独测试过? 端点1上传那个框框 是通过端点1上传的,原理和端点2是一样的,只是单次只能上传8字节.


用仿真器在电脑上显示的 DataLong = length; 直接把收到的数据长度给一个寄存器。通过仿真就可以看到数据长度了。。。。

现在知道是什么原因了,是那个类型说明,在函数里面说明数据类型的话,显示的数据长度就有问题,在函数外面说明数据类型就正确了。。。

接收的数据和你发送的数据长度相等,并且是按位取反。这都没有问题了

然后我用那个Test的文件夹里面的上位机测试程序。显示的是 一大堆

这是什么问题啊????


S1-T1-C2441 return data error at 3: 01H S1-T1-C2441 return data error at 4: 01H S1-T1-C2441 return data error at 5: 01H S1-T1-C2441 return data error at 6: 01H S1-T1-C2441 return data error at 7: 01H S1-T1-C2441 return data error at 8: 01H S1-T1-C2441 return data error at 9: 01H S1-T1-C2441 return data error at 10: 01H


我也遇到4,5,6楼的问题,还是没有解决,每步大于10ms的延时都没有用

奇怪的是单步(按住F10)把第一个64位走完居然能走到第二个64位,我一生气,在每个读字节加了很大延时,都不行,不懂,感觉这个芯片有点什么问题,怎么都遇到这个问题


出现上述的情况主要还是时序上面的问题,建议你把三个读写子函数贴出来看下。


我的硬件是MC9S08,模拟总线访问flash芯片和ch375芯片,总线频率20MHz(50ns), MC9S08访问端口需要5个总线周期,片选择信号在主程序的每个指令前设置,整个命令操作完毕后取消 出现访问第一个64字节可以,但是第二个就出现不能访问,或者一直按住F10仿真才能运行

void usb_send_cmd(uint8_t cmd) { USB_PORT_A0 = 1; USB_PORT_DATA_DIR = USB_PORT_DATA_DIR_OUT; USB_PORT_DATA = cmd; USB_PORT_WR = 0; USB_PORT_WR = 1; } void usb_send_data(uint8_t dat) { USB_PORT_A0 = 0; USB_PORT_DATA_DIR = USB_PORT_DATA_DIR_OUT; USB_PORT_DATA = dat; USB_PORT_WR = 0; delay_05us(2); USB_PORT_WR = 1; delay_05us(2); } uint8_t usb_rev_data(void) { uint8_t dat; USB_PORT_A0 = 0; USB_PORT_DATA_DIR = USB_PORT_DATA_DIR_IN; USB_PORT_RE = 0; delay_05us(2); dat = USB_PORT_DATA; USB_PORT_RE = 1; return dat; }

这是我看了本帖的修改的,在主程序中,将所有有关CS的语句全部去掉,但是好像问题更严重,CMD_CHECK_EXIST都不能得到正确返回值,

void usb_send_cmd(uint8_t cmd) { delay_05us(3); USB_PORT_DATA = cmd; USB_PORT_A0 = 1; // 选择CH375的命令口 USB_PORT_DATA_DIR = USB_PORT_DATA_DIR_OUT; //对于标准双向I/O,请在此设置为输出方向 //CH375_RD = 1; // 如果I/O默认电平是高电平,那么这是可选操作 USB_PORT_CS = 0; USB_PORT_WR = 0; //CH375_CS = 0; // 对于高速单片机,该指令用于延时,以便向CH375_WR产生宽度至少为80nS的低电平脉冲 USB_PORT_WR = 1; USB_PORT_CS = 1; USB_PORT_A0 = 0; USB_PORT_DATA_DIR = USB_PORT_DATA_DIR_IN; // 对于标准双向I/O,请在此设置为输入方向 //CH375_D0_D7 = 0xFF; // 对于准双向I/O,请在此设置输出全高电平 delay_05us(3); } void usb_send_data(uint8_t dat) { USB_PORT_DATA = dat; USB_PORT_DATA_DIR = USB_PORT_DATA_DIR_OUT; //对于标准双向I/O,请在此设置为输出方向 USB_PORT_CS = 0; USB_PORT_WR = 0; // CH375_CS = 0; 对于高速单片机,该指令用于延时,以便向CH375_WR产生宽度至少为80nS的低电平脉冲 USB_PORT_WR = 1; USB_PORT_CS = 1; USB_PORT_DATA_DIR = USB_PORT_DATA_DIR_IN; // 对于标准双向I/O,请在此设置为输入方向 //CH375_D0_D7 = 0xFF; // 对于准双向I/O,请在此设置输出全高电平 delay_05us(1); // 因为MCS51单片机较慢所以实际上无需延时 } uint8_t usb_rev_data(void) { uint8_t dat; // 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 delay_05us(1); // 因为MCS51单片机较慢所以实际上无需延时 USB_PORT_DATA_DIR = USB_PORT_DATA_DIR_IN; // 对于标准双向I/O,请在此设置为输入方向 //CH375_D0_D7 = 0xFF; // 对于准双向I/O,请在此设置输出全高电平 USB_PORT_CS = 0; USB_PORT_RE = 0; // CH375_CS = 0; 对于高速单片机,该指令用于延时,以便向CH375_RD产生宽度至少为80nS的低电平脉冲 dat = USB_PORT_DATA; USB_PORT_RE = 1; USB_PORT_CS = 1; // USB_PORT_DATA = 0xFF; 对于准双向I/O,请在此设置输出全高电平 return(dat); }


unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */ 为什么是 0xBDF1和 0xBCF0 呢?

还有资料里有这样一段话: U4(单片机89C51 等)用于测试CH372 的USB 数据通讯功能,本例中CH372 的地址A0 由U4 的 P20 驱动,CH372 的片选线CS#由U4 的P21 驱动,所以CH372 的命令口的地址可以是FDXXH(例子程 序中使用地址BDF1H),数据口的地址可以是FCXXH(例子程序中使用地址BCF0H)

只看见资料上说跟硬件电路有关,到底是怎么得来这个数的呢?

void CH375_WR_CMD_PORT( unsigned char cmd ) { /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */ delay2us(); CH375_CMD_PORT=cmd; delay2us(); } 上面这个函数是向命令端写入命令,CH372资料上面写的是A0=0的时候才能写命令,为什么这个函数不需要,而且没有遵守资料上所说的时序。 如果是那样的话,单片机为什么要跟 #CS #WR #RD 连接,连接了之后程序根本就没对这几个引脚操作,连接起来干嘛的?以上两个问题谁能回答我!


至于地址怎么定义的,你可以参考一下51MCU的总线部分,其实就是一个XRAM的地址。 您需要查一下相关教材,这是标准做法。


第一遍能读数据长度成功,不过不是64而是0x24,不知道为什么,读完这0x24字节数据后,进入第二遍 第一个if 就返回了,错误码是1F,为什么呢????

while(cnt--) { if(xWaitInterrupt() != USB_INT_DISK_READ)break; //等待就绪 出错跳出 xWriteCH375Cmd(CMD_RD_USB_DATA); //发读数据命令 temp = xReadCH375Data(); //读数据长度 while(temp--)*buffer++ = xReadCH375Data(); //依次读出数据 SysTickDelay(10); xWriteCH375Cmd(CMD_DISK_RD_GO); //发继续命令 }


返回0x1f说明存储器操作失败,前面的初始化操作是否都已经成功?特别是DISK_READY命令


write_command(CMD_CHECK_EXIST); /* 1. 测试工作状态是否正常? */ write_data(0x5a); /* 测试数据 */ c = read_data(); for(j=0;j<100;j++) /* 延时等待U盘进入正常工作状态 */ for(i=0; i<10000; i++); for(j=0;j<100;j++) for(i=0; i<10000; i++); 这里为什么延延时啊?


dddddddd!!!新手报道!!多支持[Emot]12[/Emot][Emot]27[/Emot]


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