[求助] 讀寫金士頓U盤的問題?

我用ch375B操作2G金士頓U盤. 用的lib6, 根據(jù)exam8.

可是執(zhí)行到 CH375DiskReady() == ERR_SUCCESS 就不往下執(zhí)行了, 這是為什么?

現(xiàn)象是: 發(fā)送了一次"Wait for USB Ready"后面就什么也不發(fā)送了,所以我判斷執(zhí)行到此就進入死循環(huán)了還是怎么回事? 大蝦指點!

部分代碼如下:

//----------------------------------------------------- i = CH375LibInit(); mStopIfError(i);

// while(1) // { while(CH375DiskStatus < DISK_CONNECT) { if(CH375DiskConnect() == ERR_SUCCESS) break; Delay(2000); } // } LED_OUT_ACT(); SendString("USB Connected \n"); Delay(2000); for(i = 0; i < 5; i++) { Delay(1000); SendString("Wait for USB Ready \n"); if(CH375DiskReady() == ERR_SUCCESS) { break; SendString("USB OK \n"); } } SendString("USB Ready \n"); i = CH375DiskSize(); mStopIfError(i);

//-----------------------------------------------------

CH375DiskReady()之前測試磁盤緩沖區(qū),寫入與讀出的數(shù)據(jù)是否相同


磁盤緩沖區(qū)? 是指我的外部ram么?


我把CH375DiskReady()那段判斷注釋掉后,發(fā)現(xiàn)運行到CH375FileOpen()有運行不下去.

是不是我的庫或者硬件連接的問題? 關(guān)鍵是看不到子函數(shù).

另外,我執(zhí)行完CH375DiskSize()后發(fā)現(xiàn)mDiskSizeSec為-67372037,奇怪??

代碼如下:

//------------------------------------------- SendString("USB Ready \n"); i = CH375DiskSize(); mStopIfError(i); // printf("TotalSize = %u MB \n", (unsigned int)( mCmdParam.DiskSize.mDiskSizeSec * (CH375vSectorSize / 512) / 2048)); LED_RUN_ACT();

mCopyCodeStringToIRAM(mCmdParam.Open.mPathName, "/MY_ADC.TXT"); SendString("File name copied\n"); i = CH375FileOpen(); SendString("File Opened! \n");

//-------------------------------------------


你需要仔細檢查一下DISK_BASE_BUF是不是有問題!一般是緩沖益出,不足等原因造成這個現(xiàn)象. CH375DiskReady()對90%的U盤來說一定要通過,否則操作不起來.


我用的32k的62256, 我的存儲區(qū)定義如下,大蝦幫我看看?

//------------------------------ // 外部RAM的磁盤數(shù)據(jù)緩沖區(qū)的起始地址,從該單元開始的緩沖區(qū)長度為SECTOR_SIZE #define DISK_BASE_BUF_ADDR 0x0400 // 默認的磁盤數(shù)據(jù)緩沖區(qū)大小為512字節(jié),建議選擇為2048甚至4096以支持某些大扇區(qū)的U盤, // 為0則禁止在.H文件中定義緩沖區(qū)并由應用程序在pDISK_BASE_BUF中指定 #define DISK_BASE_BUF_LEN 4096 // 外部RAM的文件數(shù)據(jù)緩沖區(qū)的起始地址,緩沖區(qū)長度不小于一次讀寫的數(shù)據(jù)長度 #define FILE_DATA_BUF_ADDR 0x1400 // 外部RAM的文件數(shù)據(jù)緩沖區(qū),緩沖區(qū)長度不小于一次讀寫的數(shù)據(jù)長度,本例要求不小于0x400即可 #define FILE_DATA_BUF_LEN 0x6000 //------------------------------


RAM定義沒問題,按帖2作下測試 另,把完整的程序貼出來


我做了兩個字節(jié)RAM的測試,好象沒問題呢. 所有代碼如下:

//=============================================

/********************************************************* U ceshi *********************************************************/ #include #include #include #include

#define ulong unsigned long #define uint unsigned int #define uchar unsigned char

// ----- LED Port -----

sbit LED1 = P3^5; sbit LED2 = P3^4;

// ----- CH375 Port ----

sbit CH375_INT = P3^2;

// 磁盤讀寫的數(shù)據(jù)的復制方式,1為"單DPTR復制",2為"雙DPTR復制",3為"單DPTR和P2+R0復制" #define LIB_CFG_DISK_IO 3 // 文件讀寫的數(shù)據(jù)的復制方式,0為"外部子程序",1為"單DPTR復制",2為"雙DPTR復制",3為"單DPTR和P2+R0復制" #define LIB_CFG_FILE_IO 3 // CH375的INT#引腳連接方式,0為"查詢方式",1為"中斷方式" #define LIB_CFG_INT_EN 0 // CH375命令端口的I/O地址 #define CH375_CMD_PORT_ADDR 0xB001 // CH375數(shù)據(jù)端口的I/O地址 #define CH375_DAT_PORT_ADDR 0xB000 // 外部RAM的磁盤數(shù)據(jù)緩沖區(qū)的起始地址,從該單元開始的緩沖區(qū)長度為SECTOR_SIZE #define DISK_BASE_BUF_ADDR 0x0400 // 默認的磁盤數(shù)據(jù)緩沖區(qū)大小為512字節(jié),建議選擇為2048甚至4096以支持某些大扇區(qū)的U盤, // 為0則禁止在.H文件中定義緩沖區(qū)并由應用程序在pDISK_BASE_BUF中指定 #define DISK_BASE_BUF_LEN 8192 // 外部RAM的文件數(shù)據(jù)緩沖區(qū)的起始地址,緩沖區(qū)長度不小于一次讀寫的數(shù)據(jù)長度 #define FILE_DATA_BUF_ADDR 0x2400 // 外部RAM的文件數(shù)據(jù)緩沖區(qū),緩沖區(qū)長度不小于一次讀寫的數(shù)據(jù)長度,本例要求不小于0x400即可 #define FILE_DATA_BUF_LEN 0x5000 // P3.2, CH375_INT, CH375的中斷線INT#引腳,連接CH375的INT#引腳,用于查詢中斷狀態(tài) #define CH375_INT_WIRE CH375_INT // 未調(diào)用CH375FileEnumer程序故禁止以節(jié)約代碼 #define NO_DEFAULT_CH375_F_ENUM 1 // 未調(diào)用CH375FileQuery程序故禁止以節(jié)約代碼 #define NO_DEFAULT_CH375_F_QUERY 1

#include "CH375HF6.H" uint total;

#define LED_OUT_INIT() {LED1 = 1;} #define LED_OUT_ACT() {LED1 = 0;} #define LED_OUT_INACT() {LED1 = 1;}

#define LED_RUN_ACT() {LED2 = 0;} #define LED_RUN_INACT() {LED2 = 1;}

#define LED_WR_ACT() {LED1 = 0;} #define LED_WR_INACT() {LED1 = 1;}

//-------子函數(shù)實現(xiàn)區(qū)------- void SystemInit(void) { ET0 = 1; //T0中斷允許 ES = 1; //串口中斷允許 TMOD = 0x20; //定時器1自動重載方式,定時器0工作在方式1(16位計數(shù)) TL1 = 0xF7; //設置波特率9600 TH1 = 0xF7; SCON = 0x50; //串口工作在方式2(10位異步收發(fā)) PCON = 0x00; //電源控制器寄存器設置 TR1 = 1; //啟動T1計數(shù)(啟動波特率計數(shù)) // AUXR = 0x00; //訪問內(nèi)部擴展RAM允許

}

void SendOneByte(unsigned char temp) { SBUF = temp; while(TI == 0); TI = 0; }

void Delay(unsigned int t) // Delay about 3.5 uS { do { _nop_(); }while(t--); }

uchar mCopyCodeStringToIRAM(uchar idata *iDestination, uchar code *iSource) { uchar i = 0; while(*iDestination = *iSource) { iDestination++; iSource++; i++; } return i; }

void SendString(uchar code *iString) { while(*iString) { SendOneByte(*iString); iString++; } }

void SendRAMString(uchar xdata *pString) { while(*pString) { SendOneByte(*pString); pString++; } }

void mStopIfError(uchar iError) { if(iError == ERR_SUCCESS) return; // 操作成功 while(1) { LED_OUT_ACT(); // LED閃爍 Delay(10000); LED_OUT_INACT(); Delay(10000); } }

void mFlushBufferToDisk(uchar force) { uchar i; ulong NewSize; if(force) // 強制刷新 { // 將緩沖區(qū)中的字節(jié)數(shù)轉(zhuǎn)換為扇區(qū)數(shù)(除以CH375vSectorSize),長度加上CH375vSectorSize-1用于確保寫入最后的零頭數(shù)據(jù) mCmdParam.Write.mSectorCount = (total + CH375vSectorSize - 1) / CH375vSectorSize; // 以扇區(qū)為單位向文件寫入數(shù)據(jù),寫入緩沖區(qū)中的所有數(shù)據(jù),含最后的零頭數(shù)據(jù) i = CH375FileWrite(); mStopIfError(i); // 有些U盤可能會要求在寫數(shù)據(jù)后等待一會才能繼續(xù)操作,所以如果在某些U盤中發(fā)生數(shù)據(jù)丟失現(xiàn)象,建議在每次寫入數(shù)據(jù)后稍作延時在繼續(xù)操作 Delay(1000); // 將剛才已寫入U盤的零頭數(shù)據(jù)復制到緩沖區(qū)的頭部 memcpy(FILE_DATA_BUF + 0, FILE_DATA_BUF + (total & ~(CH375vSectorSize - 1)), total & (CH375vSectorSize - 1)); // 緩沖區(qū)中只剩下剛才已寫入U盤的零頭數(shù)據(jù),繼續(xù)保留在緩沖區(qū)中是為了方便以后在其后面追加數(shù)據(jù) total &= CH375vSectorSize - 1; // if(total) // 以扇區(qū)為單位,有零頭數(shù)據(jù),計算出真正的文件長度(有效數(shù)據(jù)的長度) NewSize = CH375vFileSize - CH375vSectorSize + total; else // 以扇區(qū)為單位,沒有零頭數(shù)據(jù),文件長度是CH375vSectorSize的倍數(shù) NewSize = CH375vFileSize; // 輸入?yún)?shù): 新的文件長度,扇區(qū)模式下涉及到零頭數(shù)據(jù)不便自動更新長度 mCmdParam.Modify.mFileSize = NewSize; // 輸入?yún)?shù): 新的文件屬性,為0FFH則不修改 mCmdParam.Modify.mFileAttr = 0xFF; // 輸入?yún)?shù): 新的文件時間,為0FFH則不修改 mCmdParam.Modify.mFileTime = 0xFFFF; // 輸入?yún)?shù): 新的文件日期,為0FFH則不修改 mCmdParam.Modify.mFileDate = 0xFFFF; // 修改當前文件的信息,修改文件長度 i = CH375FileModify(); mStopIfError(i); // 移到文件的尾部,以扇區(qū)為單位,所以會忽略文件尾部的零頭數(shù)據(jù) mCmdParam.Locate.mSectorOffset = 0xFFFFFFFF; // 重新回到原文件的尾部,下面如果再寫入數(shù)據(jù)將覆蓋尾部零頭數(shù)據(jù),不過該零頭數(shù)據(jù)有一份副本保留在緩沖區(qū)中 i = CH375FileLocate(); mStopIfError(i); } // 緩沖區(qū)中的數(shù)據(jù)快要滿了,所以應該先將緩沖區(qū)中的原有數(shù)據(jù)寫入U盤 else if(total >= FILE_DATA_BUF_LEN - CH375vSectorSize) { // 將緩沖區(qū)中的字節(jié)數(shù)轉(zhuǎn)換為扇區(qū)數(shù)(除以CH375vSectorSize),最后的零頭數(shù)據(jù)先不管 mCmdParam.Write.mSectorCount = total / CH375vSectorSize; // 以扇區(qū)為單位向文件寫入數(shù)據(jù),寫入緩沖區(qū)中的所有數(shù)據(jù),不含最后的零頭 i = CH375FileWrite(); mStopIfError(i); // 將剛才未寫入U盤的零頭數(shù)據(jù)復制到緩沖區(qū)的頭部 memcpy(FILE_DATA_BUF + 0, FILE_DATA_BUF + (total & ~(CH375vSectorSize - 1)), total & (CH375vSectorSize - 1)); // 緩沖區(qū)中只剩下剛才未寫入U盤的零頭數(shù)據(jù) total &= CH375vSectorSize -1; } }

void main(void) { ulong idata lDataTemp = 0; uchar idata i = 0; uchar idata dataTemp1 = 0; uchar idata dataTemp2 = 0; uchar idata dataTemp3 = 0;

SystemInit();

LED_OUT_INIT(); LED_OUT_ACT(); Delay(10000); LED_OUT_INACT();

SendString("MCU Start \n");

i = CH375LibInit(); mStopIfError(i);

// FILE_DATA_BUF[0] = 'a'; // FILE_DATA_BUF[1] = 't';

// SendOneByte(FILE_DATA_BUF[1]); // SendOneByte(FILE_DATA_BUF[0]); // SendOneByte(i + 0x30);

while(CH375DiskStatus < DISK_CONNECT) { if(CH375DiskConnect() == ERR_SUCCESS) break; Delay(2000); }

LED_OUT_ACT(); SendString("USB Connected \n"); Delay(2000); for(i = 0; i < 5; i++) { Delay(1000); SendString("Wait for USB Ready \n"); if(CH375DiskReady() == ERR_SUCCESS) { break; SendString("USB OK \n"); } } SendString("USB Ready \n"); i = CH375DiskSize(); mStopIfError(i);

sprintf(FILE_DATA_BUF, "%ld,\n", mCmdParam.DiskSize.mDiskSizeSec); SendRAMString(FILE_DATA_BUF); // printf("TotalSize = %u MB \n", (unsigned int)( mCmdParam.DiskSize.mDiskSizeSec * (CH375vSectorSize / 512) / 2048)); LED_RUN_ACT();

mCopyCodeStringToIRAM(mCmdParam.Open.mPathName, "/MY_ADC.TXT"); SendString("File name copied\n"); i = CH375FileOpen(); SendString("File Opened! \n"); if(i == ERR_SUCCESS) { mCmdParam.Locate.mSectorOffset = 0xFFFFFFFF; i = CH375FileLocate(); mStopIfError(i); total = CH375vFileSize & (CH375vSectorSize - 1); CH375vFileSize += CH375vSectorSize - 1; mCmdParam.Read.mSectorCount = 1; i = CH375FileRead(); mStopIfError(i); CH375vFileSize -= CH375vSectorSize - 1; mCmdParam.Locate.mSectorOffset = 0xFFFFFFFF; i = CH375FileLocate(); mStopIfError(i); } else if(i == ERR_MISS_FILE) { LED_WR_ACT(); i = CH375FileCreate(); mStopIfError(i); SendString("File Created \n"); total = 0; } else { mStopIfError(i); } LED_WR_ACT(); total += sprintf(FILE_DATA_BUF + total, "在本次添加數(shù)據(jù)之前,該文件已有數(shù)據(jù)的長度是 %ld 字節(jié)\xd\xa", CH375vFileSize ); mFlushBufferToDisk(0);

total += sprintf( FILE_DATA_BUF + total, " ********************************* " ); /*


我用下面代碼測試了所有的ram區(qū),貌似沒問題.

//========

for(j = 0; j < 31744; j++) { if(j < 4096) DISK_BASE_BUF[j] = 'A'; else if(j < 30000) DISK_BASE_BUF[j] = 'B'; else DISK_BASE_BUF[j] = 'C'; }

for(j = 0; j < 31744; j++) { SendOneByte(DISK_BASE_BUF[j]); }

//========


問題貌似解決了, 我用的 "單DPTR + P2 + R0"復制不行,改成 "單DPTR"復制即可. 我用的STC89LE58單片機.


這個問題是因為自帶1K外部RAM的單片機不支持P2+R0的復制方式,你可以采用雙DPTR的方式來操作U盤,或者直接換一個AT89C55WD這個單片機就可以了


該單片機自帶1KB的外部RAM,選用 "單DPTR + P2 + R0"這個方式時,必須把自帶RAM禁用,即配置AUXR寄存器


恩,是的. 用這款的原因也就是灌程序方便.


只有登錄才能回復,可以選擇微信賬號登錄

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