【原創(chuàng)】畢業(yè)設(shè)計(jì)用375A 我有點(diǎn)后悔

1 個(gè)月前 我的畢業(yè)設(shè)計(jì)開始了 我看中了375 的直接讀扇區(qū) 不用處理繁復(fù)的usb通信 所以選用了 它

現(xiàn)在 作完了 不用程序庫(kù) 已經(jīng)可以實(shí)現(xiàn) fat16 fat32 的程序庫(kù)有的功能都有 任意目錄下的文件讀寫 ,新建文件與目錄 分級(jí)打開目錄 任意字節(jié)的讀寫 支持多個(gè)數(shù)據(jù)緩沖 不過 底層的扇區(qū)讀寫 并不穩(wěn)定 6個(gè)u盤 只有 較舊的兩個(gè)可以完全正常了 其他的讀寫都不正常 看了是disk_init 不行

但是 這個(gè)問題 我也沒辦法 我試過用他的程序庫(kù)進(jìn)行 是可以通過的 但是程序庫(kù)的初始化方法 卻是沒有源碼公開的

其實(shí) 375 我們需要的不是你的 fat 讀寫方法 ,而是你的 底層扇區(qū)讀寫的兼容性 為什么你們不公開呢。

我用 sl811 程序兼容性好多了 起碼底層沒問題 。 我真想知道 ch375 不用你的程序庫(kù) 你支持多少個(gè)u盤! 這是我的板子,

20075161313053.jpg

是有這個(gè)問題,我現(xiàn)在就遇到了,換了好幾個(gè)USB設(shè)備,只有清華紫光(1G),還有個(gè)微盤(32M)的能識(shí)別,其他愛國(guó)者(256M),聯(lián)想(32M)的不行,不知道為什么


別發(fā)牢騷,我在這兒發(fā)表過兩次不使用庫(kù)的初始化,只是這兒的管理員居于某些目的不肯置頂. 你不要提SL811,如果你用SL811的話未必能怎么樣,我可是寫過的.那樣的話你需要看的東西就更多了,光一個(gè)枚舉就麻煩死了,出錯(cuò)后比CH375A更加麻煩,你現(xiàn)在找不到問題的解決辦法說明你已經(jīng)沒有看MASS Storage Class的UFI命令集與Bulk Only協(xié)議,你真看了就自然會(huì)想到解決辦法. 建議你去下載一個(gè)BusHound,看看你出錯(cuò)的優(yōu)盤的通信數(shù)據(jù),然后再去看看協(xié)議,就知道解決方法了.


我找到了鏈接地址,你去看看,這是某些優(yōu)盤做法有問題,就是出錯(cuò)后必須讀出錯(cuò)誤,否則不處理,而某些優(yōu)盤則沒有這么嚴(yán)格.

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


我是剛開始用CH375做主機(jī)讀U盤的,在開發(fā)過程中遇到很多困難,其中就有U盤兼容性問題, 能否給個(gè)CH375初始化源程序?謝謝了 個(gè)人信息保護(hù),已隱藏


Skunk可否把你的 任意目錄下的文件讀寫 ,新建文件與目錄 的程序給我份 謝謝 個(gè)人信息保護(hù),已隱藏


樓主大哥 能把你做的板的電路圖和pcb圖發(fā)給我嗎 我畫的圖出了很多問題 萬分感謝 我的郵箱是個(gè)人信息保護(hù),已隱藏


Skunk 不好意思 全部通過了但還是讀扇區(qū)出錯(cuò)


/* *************************************************************************************** * 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) { /* 寫數(shù)據(jù) */ u_int8_t i; ch375_dat_port = dat; for (i = 1; i != 0; i--); } u_int8_t ch375_r_dat_port(void) { /* 讀數(shù)據(jù) */ u_int8_t i; for (i = 1; i != 0; i--); return (ch375_dat_port); } u_int8_t wait_int(void) { /* 等待中斷響應(yīng) */ while (CH375_INT_WIRE); ch375_w_cmd_port(CMD_GET_STATUS); return (ch375_r_dat_port()); } /***** FUNCTION ********************************************************************** ** 函數(shù)名稱: init_ch375 ** 功能描述: CH375初始化函數(shù) ** ** - PARAMETER ------------------------------------------------------------------------ ** Mode Type Name Description ** ------------------------------------------------------------------------------------ ** return: u_int8_t 0 成功 失敗 返回錯(cuò)誤代碼 ** ------------------------------------------------------------------------------------ ** Revision: none **************************************************************************************/ u_int8_t init_ch375(void) { u_int16_t i; u_int8_t c; ch375_w_cmd_port(CMD_CHECK_EXIST); /* 測(cè)試工作狀態(tài) */ ch375_w_dat_port(0x55); /* 測(cè)試數(shù)據(jù) */ c = ch375_r_dat_port(); /* 返回?cái)?shù)據(jù)應(yīng)該是測(cè)試數(shù)據(jù)取反 */ if (c != 0xaa) { /* CH375出錯(cuò) */ ch375_w_cmd_port(CMD_RESET_ALL); /* CH375執(zhí)行硬件復(fù)位 */ for (i = 40000; i != 0; i--) { /* 延時(shí)40ms 12mhz晶振 */ } } ch375_w_cmd_port(CMD_SET_USB_MODE); ch375_w_dat_port(6); /* 模式6主機(jī)方式 自動(dòng)產(chǎn)生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 ********************************************************************** ** 函數(shù)名稱: wait_udisk ** 功能描述: 等待u盤連接 ** ** - PARAMETER ------------------------------------------------------------------------ ** Mode Type Name Description ** ------------------------------------------------------------------------------------ ** return: u_int8_t 0 成功 失敗 返回錯(cuò)誤代碼 ** ------------------------------------------------------------------------------------ ** 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盤 讀不了


我原來沒有發(fā)DISK_READY命令,我加了一下后也是可以的。我這個(gè)方法主要是保證出錯(cuò)一定處理,如果你讀不出的優(yōu)盤都跑到過DISK_RSENSE命令,就說明此方法已經(jīng)生效,但為什么對(duì)某些優(yōu)盤還是沒有用,我就不知道了。因?yàn)槟阏f用官方庫(kù)沒有問題,就排除了硬件問題。 是不是用了此方法后沒有一點(diǎn)效果??


證明我沒有騙你,給你看看我的源代碼,因?yàn)槲沂遣怀S玫膯纹瑱C(jī),且是實(shí)時(shí)系統(tǒng)寫法,所以是否看得明白就看你自己了。另外,據(jù)底層協(xié)議中的要求,在出現(xiàn)錯(cuò)誤后需要對(duì)端點(diǎn)進(jìn)行復(fù)位,延時(shí)一定時(shí)間(具體忘了)后,所以你在發(fā)出DISK_R_SENSE前加點(diǎn)延時(shí)試試。

InitUSBDisk: li r7,DISK_INIT lcall CH375WriteCmd

liw r7,GetDiskLun liw dp1l,DelayCall;中斷成功后調(diào)用 stx r7,dp1 ret

GetDiskLun: clrw r6 liw dp1l,MaxLUN;邏輯單元清0 stx r6,dp1;//最大邏輯單元 stx r6,dp1+1;//當(dāng)前邏輯單元

li r7,DISK_MAX_LUN lcall CH375WriteCmd

liw r7,GetDiskInquiry;中斷成功后調(diào)用 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;數(shù)據(jù)錯(cuò)誤,全部讀出 lcall CH375ReadData djnz r6,DISPLAY_LUNLOOP sjmp DISK_LUN_NODATA DISK_ISLUN_DATA lcall CH375ReadData lw r6,r7

liw dp1l,MaxLUN;保存所有的邏輯單元,一個(gè)個(gè)進(jìn)行文件系統(tǒng)判斷 stx r6,dp1;

DISK_LUN_NODATA

li r7,DISK_INQUIRY lcall CH375WriteCmd

liw r7,GetDiskSize;成功后調(diào)用 liw dp1l,DelayCall stx r7,dp1

liw dp1l,RetryCall liw r7,GetSense;失敗后調(diào)用 stx r7,dp1

liw dp1l,SenseRetry liw r7,DISK_LUN_NODATA;讀出錯(cuò)誤后重試函數(shù) stx r7,dp1

liw dp1l,IgnorError;允許錯(cuò)誤 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;開始檢測(cè)扇區(qū)0 liw dp1l,DelayCall stx r7,dp1 ret TestFunction: li r7h,DISK_READ;讀

li r7l,1;1個(gè)扇區(qū)

clrw r5 clrw r6

li r4,TMPRAM_PAGE li r3,TMPRAM_OFFSET

li r2,ProcMBR;處理MBR函數(shù) lcall AddSecterCmd ret


按照你的 思路改成這樣了 但是還是不行 初始化可以 但是讀盤錯(cuò)誤 中間加了延時(shí)也不行 就是較新的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); /* 讀數(shù)據(jù) */ 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); /* 出錯(cuò)處理 */ if ((err_status = wait_int()) == USB_INT_SUCCESS) { ch375_w_cmd_port(CMD_RD_USB_DATA); /* 讀數(shù)據(jù) */ 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; }


你的意思是現(xiàn)在這個(gè)寫法對(duì)一部分優(yōu)盤有效了? 讀優(yōu)盤時(shí)出錯(cuò)是指什么錯(cuò)誤?是中斷狀態(tài)為0x1f,還是讀出的值不是自己期待的值? 如果是第二種的話,可能就是我現(xiàn)在這個(gè)方法還是有兼容性問題。如果是0x1f你得判斷錯(cuò)誤狀態(tài)。你現(xiàn)在里面沒有錯(cuò)誤狀態(tài)的判斷。我現(xiàn)在只判斷了兩種,一種是設(shè)備未準(zhǔn)備好,一種是寫保護(hù)。第一種處理是重試,第二種則不處理。


用google搜索usbmass-ufi10.pdf 38頁(yè)有錯(cuò)誤結(jié)構(gòu),后面有錯(cuò)誤詳細(xì)描述。如果是出現(xiàn)錯(cuò)誤0x1f的話就讀出來看看。


其實(shí)呢 對(duì)一部分的u盤 只要是disk_INI 就行了 其他的確用什么方法都不行 還有我的盤都是沒有寫保護(hù)的


我很想知道的是,那個(gè)出錯(cuò)處理跑到?jīng)]有?


只有登錄才能回復(fù),可以選擇微信賬號(hào)登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频