【原创】毕业设计用375A 我有点后悔

1 个月前 我的毕业设计开始了 我看中了375 的直接读扇区 不用处理繁复的usb通信 所以选用了 它

现在 作完了 不用程序库 已经可以实现 fat16 fat32 的程序库有的功能都有 任意目录下的文件读写 ,新建文件与目录 分级打开目录 任意字节的读写 支持多个数据缓冲 不过 底层的扇区读写 并不稳定 6个u盘 只有 较旧的两个可以完全正常了 其他的读写都不正常 看了是disk_init 不行

但是 这个问题 我也没办法 我试过用他的程序库进行 是可以通过的 但是程序库的初始化方法 却是没有源码公开的

其实 375 我们需要的不是你的 fat 读写方法 ,而是你的 底层扇区读写的兼容性 为什么你们不公开呢。

我用 sl811 程序兼容性好多了 起码底层没问题 。 我真想知道 ch375 不用你的程序库 你支持多少个u盘! 这是我的板子,

20075161313053.jpg

是有这个问题,我现在就遇到了,换了好几个USB设备,只有清华紫光(1G),还有个微盘(32M)的能识别,其他爱国者(256M),联想(32M)的不行,不知道为什么


别发牢骚,我在这儿发表过两次不使用库的初始化,只是这儿的管理员居于某些目的不肯置顶. 你不要提SL811,如果你用SL811的话未必能怎么样,我可是写过的.那样的话你需要看的东西就更多了,光一个枚举就麻烦死了,出错后比CH375A更加麻烦,你现在找不到问题的解决办法说明你已经没有看MASS Storage Class的UFI命令集与Bulk Only协议,你真看了就自然会想到解决办法. 建议你去下载一个BusHound,看看你出错的优盘的通信数据,然后再去看看协议,就知道解决方法了.


我找到了链接地址,你去看看,这是某些优盘做法有问题,就是出错后必须读出错误,否则不处理,而某些优盘则没有这么严格.

http://wch.cn/bbs/View.asp?T=1&S=101&I=17373


我是刚开始用CH375做主机读U盘的,在开发过程中遇到很多困难,其中就有U盘兼容性问题, 能否给个CH375初始化源程序?谢谢了 个人信息保护,已隐藏


Skunk可否把你的 任意目录下的文件读写 ,新建文件与目录 的程序给我份 谢谢 个人信息保护,已隐藏


楼主大哥 能把你做的板的电路图和pcb图发给我吗 我画的图出了很多问题 万分感谢 我的邮箱是个人信息保护,已隐藏


Skunk 不好意思 全部通过了但还是读扇区出错


/* *************************************************************************************** * CH375 硬件层指令 *************************************************************************************** */ void ch375_w_cmd_port(u_int8_t cmd) { /* 写指令 */ u_int8_t i; for (i = 2; i != 0; i--); ch375_cmd_port = cmd; for (i = 2; i != 0; i--); } void ch375_w_dat_port(u_int8_t dat) { /* 写数据 */ u_int8_t i; ch375_dat_port = dat; for (i = 1; i != 0; i--); } u_int8_t ch375_r_dat_port(void) { /* 读数据 */ u_int8_t i; for (i = 1; i != 0; i--); return (ch375_dat_port); } u_int8_t wait_int(void) { /* 等待中断响应 */ while (CH375_INT_WIRE); ch375_w_cmd_port(CMD_GET_STATUS); return (ch375_r_dat_port()); } /***** FUNCTION ********************************************************************** ** 函数名称: init_ch375 ** 功能描述: CH375初始化函数 ** ** - PARAMETER ------------------------------------------------------------------------ ** Mode Type Name Description ** ------------------------------------------------------------------------------------ ** return: u_int8_t 0 成功 失败 返回错误代码 ** ------------------------------------------------------------------------------------ ** Revision: none **************************************************************************************/ u_int8_t init_ch375(void) { u_int16_t i; u_int8_t c; ch375_w_cmd_port(CMD_CHECK_EXIST); /* 测试工作状态 */ ch375_w_dat_port(0x55); /* 测试数据 */ c = ch375_r_dat_port(); /* 返回数据应该是测试数据取反 */ if (c != 0xaa) { /* CH375出错 */ ch375_w_cmd_port(CMD_RESET_ALL); /* CH375执行硬件复位 */ for (i = 40000; i != 0; i--) { /* 延时40ms 12mhz晶振 */ } } ch375_w_cmd_port(CMD_SET_USB_MODE); ch375_w_dat_port(6); /* 模式6主机方式 自动产生SOF */ for ( i = 255; i != 0; i -- ) { /* 等待操作成功,通常需要等待10uS-20uS */ c = ch375_r_dat_port(); if (c == CMD_RET_SUCCESS || c == USB_INT_CONNECT) { return 0; /* 操作成功 */ } } return c; } /***** FUNCTION ********************************************************************** ** 函数名称: wait_udisk ** 功能描述: 等待u盘连接 ** ** - PARAMETER ------------------------------------------------------------------------ ** Mode Type Name Description ** ------------------------------------------------------------------------------------ ** return: u_int8_t 0 成功 失败 返回错误代码 ** ------------------------------------------------------------------------------------ ** Revision: none **************************************************************************************/ u_int8_t wait_udisk(void) { u_int8_t err_status; u_int16_t i; err_status = wait_int(); if (err_status != USB_INT_CONNECT) { return err_status; } for (i = 60000; i != 0; i--); for (i = 60000; i != 0; i--); ch375_w_cmd_port(CMD_DISK_INIT); err_status = wait_int(); if (err_status != USB_INT_SUCCESS) { return err_status; } ch375_w_cmd_port(CMD_DISK_MAX_LUN); err_status = wait_int(); while (1) { ch375_w_cmd_port(CMD_DISK_INQUIRY); err_status = wait_int(); if (err_status == USB_INT_SUCCESS) { break; } ch375_w_cmd_port(CMD_DISK_R_SENSE); err_status = wait_int(); for (i = 60000; i != 0; i--); for (i = 60000; i != 0; i--); } while (1) { ch375_w_cmd_port(CMD_DISK_SIZE); err_status = wait_int(); if (err_status == USB_INT_SUCCESS) { break; } ch375_w_cmd_port(CMD_DISK_R_SENSE); err_status = wait_int(); for (i = 60000; i != 0; i--); for (i = 60000; i != 0; i--); } while (1) { ch375_w_cmd_port(CMD_DISK_READY); err_status = wait_int(); if (err_status == USB_INT_SUCCESS) { break; } for (i = 60000; i != 0; i--); for (i = 60000; i != 0; i--); } return 0; } 初始化是通过了 但是还是有的u盘 读不了


我原来没有发DISK_READY命令,我加了一下后也是可以的。我这个方法主要是保证出错一定处理,如果你读不出的优盘都跑到过DISK_RSENSE命令,就说明此方法已经生效,但为什么对某些优盘还是没有用,我就不知道了。因为你说用官方库没有问题,就排除了硬件问题。 是不是用了此方法后没有一点效果??


证明我没有骗你,给你看看我的源代码,因为我是不常用的单片机,且是实时系统写法,所以是否看得明白就看你自己了。另外,据底层协议中的要求,在出现错误后需要对端点进行复位,延时一定时间(具体忘了)后,所以你在发出DISK_R_SENSE前加点延时试试。

InitUSBDisk: li r7,DISK_INIT lcall CH375WriteCmd

liw r7,GetDiskLun liw dp1l,DelayCall;中断成功后调用 stx r7,dp1 ret

GetDiskLun: clrw r6 liw dp1l,MaxLUN;逻辑单元清0 stx r6,dp1;//最大逻辑单元 stx r6,dp1+1;//当前逻辑单元

li r7,DISK_MAX_LUN lcall CH375WriteCmd

liw r7,GetDiskInquiry;中断成功后调用 liw dp1l,DelayCall stx r7,dp1

ret

GetDiskInquiry: li r7,RD_USB_DATA lcall CH375WriteCmd

lcall CH375ReadData lw r6,r7 li r6h,0

ifr r6 = 0,DISK_LUN_NODATA ifr r6 = 1,DISK_ISLUN_DATA

DISPLAY_LUNLOOP;数据错误,全部读出 lcall CH375ReadData djnz r6,DISPLAY_LUNLOOP sjmp DISK_LUN_NODATA DISK_ISLUN_DATA lcall CH375ReadData lw r6,r7

liw dp1l,MaxLUN;保存所有的逻辑单元,一个个进行文件系统判断 stx r6,dp1;

DISK_LUN_NODATA

li r7,DISK_INQUIRY lcall CH375WriteCmd

liw r7,GetDiskSize;成功后调用 liw dp1l,DelayCall stx r7,dp1

liw dp1l,RetryCall liw r7,GetSense;失败后调用 stx r7,dp1

liw dp1l,SenseRetry liw r7,DISK_LUN_NODATA;读出错误后重试函数 stx r7,dp1

liw dp1l,IgnorError;允许错误 li r7,1 stx r7,dp1

ret GetDiskSize:

li r7,RD_USB_DATA lcall CH375WriteCmd

lcall CH375ReadData lw r6,r7 li r6h,0

ifr r6 = 0,DISK_INQUIRY_NODATA

DISPLAY_INQUIRYLOOP lcall CH375ReadData djnz r6,DISPLAY_INQUIRYLOOP

DISK_INQUIRY_NODATA

li r7,DISK_SIZE lcall CH375WriteCmd

liw r7,CheckDiskReady liw dp1l,DelayCall stx r7,dp1

liw dp1l,RetryCall liw r7,GetSense stx r7,dp1

liw dp1l,SenseRetry liw r7,DISK_INQUIRY_NODATA stx r7,dp1

liw dp1l,IgnorError li r7,1 stx r7,dp1

ret CheckDiskReady: li r7,DISK_READY lcall CH375WriteCmd

liw r7,TestFunction;开始检测扇区0 liw dp1l,DelayCall stx r7,dp1 ret TestFunction: li r7h,DISK_READ;读

li r7l,1;1个扇区

clrw r5 clrw r6

li r4,TMPRAM_PAGE li r3,TMPRAM_OFFSET

li r2,ProcMBR;处理MBR函数 lcall AddSecterCmd ret


按照你的 思路改成这样了 但是还是不行 初始化可以 但是读盘错误 中间加了延时也不行 就是较新的u盘就不行 u_int8_t test_udisk(u_int8_t cmd_to_do) { u_int8_t c; u_int8_t err_status; u_int16_t i,j; j = 20; /*重试20次*/ while (j--) { ch375_w_cmd_port(cmd_to_do); if ((err_status = wait_int()) == USB_INT_SUCCESS) { ch375_w_cmd_port(CMD_RD_USB_DATA); /* 读数据 */ i = ch375_r_dat_port(); while (i--) { c = ch375_r_dat_port(); } return 0; } for (i = 60000; i != 0; i--); for (i = 60000; i != 0; i--); ch375_w_cmd_port(CMD_DISK_R_SENSE); /* 出错处理 */ if ((err_status = wait_int()) == USB_INT_SUCCESS) { ch375_w_cmd_port(CMD_RD_USB_DATA); /* 读数据 */ i = ch375_r_dat_port(); while (i--) { c = ch375_r_dat_port(); } } else { return err_status; /* error */ } } return err_status; /* error */ } u_int8_t wait_udisk(void) { u_int8_t err_status; u_int16_t i; err_status = wait_int(); if (err_status != USB_INT_CONNECT) { return err_status; } for (i = 60000; i != 0; i--); for (i = 60000; i != 0; i--); ch375_w_cmd_port(CMD_DISK_INIT); err_status = wait_int(); if (err_status != USB_INT_SUCCESS) { return err_status; } ch375_w_cmd_port(CMD_DISK_MAX_LUN); err_status = wait_int(); err_status = test_udisk(CMD_DISK_INQUIRY); if (err_status != 0) { return err_status; } err_status = test_udisk(CMD_DISK_SIZE); if (err_status != 0) { return err_status; } while (1) { ch375_w_cmd_port(CMD_DISK_READY); err_status = wait_int(); if (err_status == USB_INT_SUCCESS) { break; } for (i = 60000; i != 0; i--); for (i = 60000; i != 0; i--); } return 0; }


你的意思是现在这个写法对一部分优盘有效了? 读优盘时出错是指什么错误?是中断状态为0x1f,还是读出的值不是自己期待的值? 如果是第二种的话,可能就是我现在这个方法还是有兼容性问题。如果是0x1f你得判断错误状态。你现在里面没有错误状态的判断。我现在只判断了两种,一种是设备未准备好,一种是写保护。第一种处理是重试,第二种则不处理。


用google搜索usbmass-ufi10.pdf 38页有错误结构,后面有错误详细描述。如果是出现错误0x1f的话就读出来看看。


其实呢 对一部分的u盘 只要是disk_INI 就行了 其他的确用什么方法都不行 还有我的盘都是没有写保护的


我很想知道的是,那个出错处理跑到没有?


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