我用的平臺(tái)是STM32F103,有FATFS8.3 U盤先插上 然后對(duì)CH375B 進(jìn)行如下操作: RESET_ALL 正常 CHECK_EXIST 正常 GET_IC_VER 55 正常 SET_USB_MODE 先是7模式,然后是6模式 正常 TEST_CONNECT 正常,返回中斷狀態(tài)為已連接,但未初始化 DISK_INIT 正常,返回中斷狀態(tài)初始化成功 DISK_READY 正常,返回狀態(tài)U盤準(zhǔn)備好 DISK_SIZE 正常,成功獲取U盤扇區(qū)大小為512B,和扇區(qū)數(shù)量 GET_MAX_LUN 正常,成功獲取U盤邏輯單元數(shù),只有一個(gè)邏輯單元 下面從U盤扇區(qū)LBA=0x0開始讀取1個(gè)扇區(qū)時(shí),出現(xiàn)問(wèn)題了 DISK_READ命令 然后發(fā)送了LBA地址0x00000000和扇區(qū)數(shù)0x01 然后等待第一個(gè)64B取回中斷時(shí),CH375一直沒有中斷請(qǐng)求,不知道為什么 是不是還有沒有什么命令沒設(shè)置啊,求幫助
確保前面命令都正確通過(guò),中斷狀態(tài)返回正確。DISK_READY之后就直接可以調(diào)用DISK_READ命令。具體流程可以參考一下:CH375EVT\MCS51C\MISCELL里面的例子
前面命令都正確通過(guò)的,不知道為啥讀扇區(qū)命令沒有中斷請(qǐng)求
檢查一下此時(shí)中斷腳有沒有被拉低?讀扇區(qū)的流程可以參考下面的函數(shù): UINT8 mReadSector( UINT32 iLbaStart, UINT8 iSectorCount, UINT8X *oDataBuffer ) { /* 從U盤讀取數(shù)據(jù)塊到緩沖區(qū) */ /* iLbaStart 起始扇區(qū)號(hào), iSectorCount 扇區(qū)數(shù), oDataBuffer 緩沖區(qū)起址 */ UINT16 mBlockCount; UINT8 c; CH375_WR_CMD_PORT( CMD_DISK_READ ); /* 從USB存儲(chǔ)器讀數(shù)據(jù)塊 */ CH375_WR_DAT_PORT( (UINT8)iLbaStart ); /* LBA的最低8位 */ CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 8 ) ); CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 16 ) ); CH375_WR_DAT_PORT( (UINT8)( iLbaStart >> 24 ) ); /* LBA的最高8位 */ CH375_WR_DAT_PORT( iSectorCount ); /* 扇區(qū)數(shù) */ for ( mBlockCount = iSectorCount * 8; mBlockCount != 0; mBlockCount -- ) { /* 數(shù)據(jù)塊計(jì)數(shù) */ c = mWaitInterrupt( ); /* 等待中斷并獲取狀態(tài) */ if ( c == USB_INT_DISK_READ ) { /* 等待中斷并獲取狀態(tài),USB存儲(chǔ)器讀數(shù)據(jù)塊,請(qǐng)求數(shù)據(jù)讀出 */ CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 從CH375緩沖區(qū)讀取數(shù)據(jù)塊 */ c = CH375_RD_DAT_PORT( ); /* 后續(xù)數(shù)據(jù)的長(zhǎng)度 */ while ( c -- ) *oDataBuffer++ = CH375_RD_DAT_PORT( ); /* 根據(jù)長(zhǎng)度讀取數(shù)據(jù)并保存 */ CH375_WR_CMD_PORT( CMD_DISK_RD_GO ); /* 繼續(xù)執(zhí)行USB存儲(chǔ)器的讀操作 */ } else break; /* 返回錯(cuò)誤狀態(tài) */ } if ( mBlockCount == 0 ) { c = mWaitInterrupt( ); /* 等待中斷并獲取狀態(tài) */ if ( c== USB_INT_SUCCESS ) return( 0 ); /* 操作成功 */ } return( c ); /* 操作失敗 */ }
中斷引腳沒有被拉低,我是用while 查詢的,就一直停在while這個(gè)地方 u8 USB_ReadDisk(u8 *pBuffer,u32 ReadAddr, u16 NumByteToRead) { u8 tmp; CH375_SentCMD(DISK_READ); //·¢?í?á?ì?üá? delay_ms(10); CH375_SentData((u8)(ReadAddr&0x000000FF)); //·¢?í?eê?LBAμ??· delay_ms(20); CH375_SentData((u8)((ReadAddr&0x0000FF00)>>8)); delay_ms(20); CH375_SentData((u8)((ReadAddr&0x00FF0000)>>16)); delay_ms(20); CH375_SentData((u8)((ReadAddr&0xFF000000)>>24)); delay_ms(20); CH375_SentData((u8)NumByteToRead); //·¢?íòa?áμ?éè??êy delay_ms(100); while(1) { while(INTER); CH375_SentCMD(GET_STATUS); delay_ms(200); tmp = CH375_ReadData(); if(tmp == USB_INT_DISK_READ) { CH375_SentCMD(RD_USB_DATA); tmp = CH375_ReadData(); if(tmp) for(;tmp>0;tmp--) { *pBuffer = CH375_ReadData(); pBuffer++; } else return 1; CH375_SentCMD(DISK_RD_GO); }else if(tmp == USB_INT_SUCCESS) break; else if(tmp == USB_INT_DISK_ERR) return 1; } return 0; }
那說(shuō)明你中斷沒有產(chǎn)生,有可能是你中斷配置問(wèn)題或者是發(fā)送的數(shù)據(jù)有問(wèn)題。那你測(cè)試一下寫會(huì)不會(huì)產(chǎn)生中斷?
我沒有用單片機(jī)的中斷輸入,就是IO口查詢,CH375就沒有向單片機(jī)請(qǐng)求中斷,INT引腳沒有拉低,不知道為啥,函數(shù)發(fā)送的數(shù)據(jù)LBA起始地址為0x00000000,數(shù)據(jù)長(zhǎng)度為0x01,這個(gè)應(yīng)該不會(huì)錯(cuò)吧,怎么就無(wú)法讀取扇區(qū)呢。DISK_SIZE命令都能正確獲取扇區(qū)數(shù)和扇區(qū)大小,說(shuō)明CH375基本通信正常的嘛,這是我的程序你幫我看看
void CH375_SentCMD(u8 cmd) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DATAPIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); A0 = 1; DATAout(cmd); WR = 0; delay_ms(1); WR = 1; return ; }
void CH375_SentData(u8 data) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DATAPIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStructure); A0 = 0; DATAout(data); WR = 0; delay_ms(1); WR = 1; return ; }
u8 CH375_ReadData() { u8 tmp; GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DATAPIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOC, &GPIO_InitStructure); A0 = 0; RD = 0; delay_ms(1); tmp = DATAin; RD = 1; return tmp; }
u8 USB_ReadDisk(u8 *pBuffer,u32 ReadAddr, u16 NumByteToRead) { u8 tmp; CH375_SentCMD(DISK_READ); //·¢?í?á?ì?üá? delay_ms(10); CH375_SentData((u8)(ReadAddr)); //·¢?í?eê?LBAμ??· delay_ms(20); CH375_SentData((u8)(ReadAddr>>8)); delay_ms(20); CH375_SentData((u8)(ReadAddr>>16)); delay_ms(20); CH375_SentData((u8)(ReadAddr>>24)); delay_ms(20); CH375_SentData((u8)NumByteToRead); //·¢?íòa?áμ?éè??êy delay_ms(100); while(1) { while(INTER); CH375_SentCMD(GET_STATUS); delay_ms(200); tmp = CH375_ReadData(); if(tmp == USB_INT_DISK_READ) { CH375_SentCMD(RD_USB_DATA); tmp = CH375_ReadData(); if(tmp) for(;tmp>0;tmp--) { *pBuffer = CH375_ReadData(); pBuffer++; } else return 1; CH375_SentCMD(DISK_RD_GO); }else if(tmp == USB_INT_SUCCESS) break; else if(tmp == USB_INT_DISK_ERR) return 1; } return 0; }
unsigned long int sectors; u16 sectorsize; u8 USB() { u8 state,res; u16 tmp; CH375_GPIOInit(); CS = 1; A0 = 1; WR = 1; RD = 1; CS = 0; CH375_SentCMD(RESET_ALL);//RESET ALL delay_ms(40); CH375_SentCMD(CHECK_EXIST);//CHECK_EXIST delay_ms(5); CH375_SentData(0xF0); delay_ms(5); tmp = CH375_ReadData(); if(tmp == 0x0F) printf("CH375 works!\r\n"); else printf("CH375 failed,back data is%d\r\n",tmp); CH375_SentCMD(GET_IC_VER); //GET_IC_VER delay_ms(5); tmp = CH375_ReadData(); printf("IC VER IS:%d\r\n",tmp&0x3F); CH375_SentCMD(SET_USB_MODE); delay_ms(5); CH375_SentData(0x07); delay_ms(5); tmp = CH375_ReadData(); if(tmp == CMD_RET_SUCCESS) printf("USB mode set successfully!\r\n"); else if(tmp == CMD_RET_ABORT) printf("USB mode set failed!\r\n"); //if((tmp == 0x15)||(tmp == 0x16)) CH375_SentCMD(SET_USB_MODE); delay_ms(5); CH375_SentData(0x06); delay_ms(5); tmp = CH375_ReadData(); if(tmp == CMD_RET_SUCCESS) printf("USB mode set successfully!\r\n"); else printf("USB mode set failed!\r\n"); CH375_SentCMD(TEST_CONNECT); delay_ms(5); tmp = CH375_ReadData(); if(tmp == 0x15) printf("USB device has connected,but not init\r\n"); else if(tmp == 0x16) printf("USB device has disconnected\r\n"); else printf("USB device is ready\r\n"); CH375_SentCMD(DISK_INIT);//3?ê??ˉUSBéè±? delay_ms(5); while(INTER); CH375_SentCMD(GET_STATUS); delay_ms(100); tmp = CH375_ReadData(); // delay_ms(20); if(tmp == USB_INT_SUCCESS) { printf("USB device Initialize Successfully!\r\n"); res = 0; } else if((tmp == USB_INT_DISK_ERR)||(tmp == USB_INT_BUF_OVER)) { printf("Unknown USB device\r\n"); res = 1; } else if(tmp == USB_INT_DISCONNECT) { printf("USB device has been disconnected\r\n"); res = 1; } else if(tmp == USB_INT_CONNECT) printf("USB device has been connected\r\n"); else { printf("USB Initialize Failed,bakc code is %d\r\n",tmp); res = 1; } if(!INTER) printf("中斷請(qǐng)求未消除\r\n"); CH375_SentCMD(DISK_READY); delay_ms(5); while(INTER); CH375_SentCMD(GET_STATUS); delay_ms(400); tmp = CH375_ReadData(); if(tmp == USB_INT_SUCCESS) printf("USB Disk is ready!\r\n"); else{ printf("USB Disk is not ready!\r\n"); } delay_ms(500); CH375_SentCMD(DISK_SIZE); delay_ms(5); while(INTER); CH375_SentCMD(GET_STATUS); // delay_ms(5); tmp = CH375_ReadData(); if(tmp == USB_INT_SUCCESS) { CH375_SentCMD(RD_USB_DATA); tmp = CH375_ReadData(); printf("data lenth is %d\r\n",tmp); if(tmp) { for(tmp = 0;tmp<4;tmp++) { sectors <<= 8; sectors |= CH375_ReadData(); } printf("扇區(qū)數(shù)為%d\r\n",sectors); for(tmp = 0; tmp<4; tmp++) { sectorsize <<= 8; sectorsize |= CH375_ReadData(); } printf("扇區(qū)大小為%d\r\n",sectorsize); printf("Total Disk Size is %lu MBytes\r\n",(sectors>>20)*512); } } CH375_SentCMD(GET_MAX_LUN);//??è?U?ìμ????-μ¥?aêy CH375_SentData(0x38); delay_ms(10); tmp = CH375_ReadData(); printf("The USB disk has %d logic unit\r\n",tmp+1); return res; }
由于沒有CH375文件級(jí)子程序庫(kù),再加上也不會(huì)用庫(kù),我用的FATFS8.3, 需要調(diào)用讀扇區(qū)的函數(shù)
看了你的程序,流程上讀扇區(qū)和獲取扇區(qū)大小都是發(fā)一個(gè)命令然后等中斷,如果能夠正常獲取扇區(qū)數(shù)和扇區(qū)大小,讀扇區(qū)操作也一樣的。 你的U盤是不是比較特殊,是不是寫保護(hù)了?我們支持FAT12/16/32的文件系統(tǒng)。你用的FATFS8.3是什么格式文件系統(tǒng)?
就是普通的U盤,我用了兩個(gè)U盤來(lái)試,第一個(gè)U盤有兩個(gè)邏輯單元,GET_MAX_LUN 命令,CH375能正確檢測(cè)到兩個(gè)邏輯單元,第二個(gè)U盤只有一個(gè)邏輯單元,CH375也正常識(shí)別,但是兩個(gè)U盤用CH375讀扇區(qū)都沒反應(yīng),沒有中斷請(qǐng)求。因?yàn)槲业膽?yīng)用設(shè)備上有SPIFLASH,SD卡存儲(chǔ)設(shè)備,所以用的FATFS來(lái)做文件系統(tǒng)。FATFS8.3支持FAT16和FAT32, 配置為支持FAT32,是這樣的,F(xiàn)ATFS先要mount掛載驅(qū)動(dòng)器,要做一系列檢查,其中有一項(xiàng)要檢查驅(qū)動(dòng)器的文件系統(tǒng)是不是能夠被支持,先要讀取一個(gè)扇區(qū)來(lái)檢查是否是FAT-VBR,DEBUG發(fā)現(xiàn)讀取的是第一個(gè)扇區(qū)的內(nèi)容,于是FATFS調(diào)用了需要自己編寫的底層讀扇區(qū)函數(shù),就是u8 USB_ReadDisk(u8 *pBuffer,u32 ReadAddr, u16 NumByteToRead)這個(gè)函數(shù),但是這個(gè)函數(shù)一直在等待CH375給出中斷請(qǐng)求,兩個(gè)U盤都是這樣,讀扇區(qū)內(nèi)容CH375一直不請(qǐng)求中斷
第一個(gè)U盤有狀態(tài)指示燈,如果主機(jī)在讀內(nèi)容的時(shí)候U盤的呼吸燈會(huì)閃爍,但是我發(fā)現(xiàn)調(diào)用u8 USB_ReadDisk(u8 *pBuffer,u32 ReadAddr, u16 NumByteToRead)這個(gè)函數(shù)讓CH375讀扇區(qū)的時(shí)候U盤狀態(tài)燈都沒閃
CH375讀U盤的流程是不是這樣的:(假設(shè)U盤已經(jīng)插上去了) MCU先RESET_ALL 復(fù)位CH375 然后CHECK_EXIST //檢查CH375是否正常工作 然后GET_IC_VER //獲取CH375芯片號(hào)(可以不要?) 然后SET_USB_MODE 先是7模式,然后是6模式,設(shè)置成6模式后,CH375是不是會(huì)自動(dòng)完成與U盤的握手枚舉,為U盤分配USB地址? TEST_CONNECT ,檢查U盤是不是連上 DISK_INIT ,這步是對(duì)U盤初始化,這個(gè)初始化是完成哪些步驟? DISK_READY 查詢U盤是否就緒,如果就緒了就可以進(jìn)行下面的步驟 DISK_SIZE 獲取U盤扇區(qū)數(shù)和扇區(qū)大小 GET_MAX_LUN 獲取U盤的邏輯單元數(shù) 然后就可以DISK_READ進(jìn)行讀取扇區(qū)操作了 是不是這個(gè)流程?
你們的那個(gè)庫(kù)函數(shù)就只是實(shí)現(xiàn)文件系統(tǒng)的功能嗎
我們提供ARM單片機(jī)的庫(kù)函數(shù),主要實(shí)現(xiàn)文件系統(tǒng)的功能。 關(guān)于操作步驟版本號(hào)是可以不要,設(shè)置模式只是設(shè)置CH375的工作模式。DISK_INIT里面做了獲取設(shè)備描述符、配置描述符、設(shè)置地址,設(shè)置配置、獲取U盤邏輯單元、獲取磁盤特性。然后DISK_READY 查詢U盤是否就緒,這一步做完之后就可以進(jìn)行扇區(qū)讀寫了。 你的操作還沒有到分析文件系統(tǒng)那一層,只是對(duì)U盤扇區(qū)進(jìn)行讀寫。
FATFS需要先讀0號(hào)扇區(qū)來(lái)檢查是否是FAT-VBR,后續(xù)的操作會(huì)進(jìn)行文件系統(tǒng)分析 這是將U盤掛載到文件系統(tǒng)之前對(duì)U盤進(jìn)行檢查的函數(shù) static FRESULT chk_mounted ( /* FR_OK(0): successful, !=0: any error occurred */ const TCHAR **path, /* Pointer to pointer to the path name (drive number) */ FATFS **rfs, /* Pointer to pointer to the found file system object */ BYTE wmode /* !=0: Check write protection for write access */ ) { BYTE fmt, b, pi, *tbl; UINT vol; DSTATUS stat; DWORD bsect, fasize, tsect, sysect, nclst, szbfat; WORD nrsv; const TCHAR *p = *path; FATFS *fs;
/* Get logical drive number from the path name */ vol = p[0] - '0'; /* Is there a drive number? */ if (vol <= 9 && p[1] == ':') { /* Found a drive number, get and strip it */ p += 2; *path = p; /* Return pointer to the path name */ } else { /* No drive number is given */ #if _FS_RPATH vol = CurrVol; /* Use current drive */ #else vol = 0; /* Use drive 0 */ #endif }
/* Check if the file system object is valid or not */ *rfs = 0; if (vol >= _VOLUMES) /* Is the drive number valid? */ return FR_INVALID_DRIVE; fs = FatFs[vol]; /* Get corresponding file system object */ if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */
ENTER_FF(fs); /* Lock file system */
*rfs = fs; /* Return pointer to the corresponding file system object */ if (fs->fs_type) { /* If the volume has been mounted */ stat = disk_status(fs->drv); if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized (has not been changed), */ if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check write protection if needed */ return FR_WRITE_PROTECTED; return FR_OK; /* The file system object is valid */ } }
/* The file system object is not valid. */ /* Following code attempts to mount the volume. (analyze BPB and initialize the fs object) */
fs->fs_type = 0; /* Clear the file system object */ fs->drv = LD2PD(vol); /* Bind the logical drive and a physical drive */ stat = disk_initialize(fs->drv); /* Initialize the physical drive */ if (stat & STA_NOINIT) /* Check if the initialization succeeded */ return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check disk write protection if needed */ return FR_WRITE_PROTECTED; #if _MAX_SS != 512 /* Get disk sector size (variable sector size cfg only) */ if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &fs->ssize) != RES_OK) return FR_DISK_ERR; #endif /* Search FAT partition on the drive. Supports only generic partitions, FDISK and SFD. */ fmt = check_fs(fs, bsect = 0);這一步就是檢查0號(hào)扇區(qū)的內(nèi)容 /* Load sector 0 and check if it is an FAT-VBR (in SFD) */ if (LD2PT(vol) && !fmt) fmt = 1; /* Force non-SFD if the volume is forced partition */ if (fmt == 1) { /* Not an FAT-VBR, the physical drive can be partitioned */ /* Check the partition listed in the partition table */ pi = LD2PT(vol); if (pi) pi--; tbl = &fs->win[MBR_Table + pi * SZ_PTE];/* Partition table */ if (tbl[4]) { /* Is the partition existing? */ bsect = LD_DWORD(&tbl[8]); /* Partition offset in LBA */ fmt = check_fs(fs, bsect); /* Check the partition */ } } if (fmt == 3) return FR_DISK_ERR; if (fmt) return FR_NO_FILESYSTEM; /* No FAT volume is found */
/* An FAT volume is found. Following code initializes the file system object */
if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */ return FR_NO_FILESYSTEM;
fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32); fs->fsize = fasize;
fs->n_fats = b = fs->win[BPB_NumFATs]; /* Number of FAT copies */ if (b != 1 && b != 2) return FR_NO_FILESYSTEM; /* (Must be 1 or 2) */ fasize *= b; /* Number of sectors for FAT area */
fs->csize = b = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ if (!b || (b & (b - 1))) return FR_NO_FILESYSTEM; /* (Must be power of 2) */
fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */ if (fs->n_rootdir % (SS(fs) / SZ_DIR)) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be sector aligned) */
tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32);
nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */ if (!nrsv) return FR_NO_FILESYSTEM; /* (BPB_RsvdSecCnt must not be 0) */
/* Determine the FAT sub type */ sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIR); /* RSV+FAT+DIR */ if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ fmt = FS_FAT12; if (nclst >= MIN_FAT16) fmt = FS_FAT16; if (nclst >= MIN_FAT32) fmt = FS_FAT32;
/* Boundaries and Limits */ fs->n_fatent = nclst + 2; /* Number of FAT entries */ fs->database = bsect + sysect; /* Data start sector */ fs->fatbase = bsect + nrsv; /* FAT start sector */ if (fmt == FS_FAT32) { if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ szbfat = fs->n_fatent * 4; /* (Required FAT size) */ } else { if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ szbfat = (fmt == FS_FAT16) ? /* (Required FAT size) */ fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); } if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (BPB_FATSz must not be less than required) */ return FR_NO_FILESYSTEM;
#if !_FS_READONLY /* Initialize cluster allocation information */ fs->free_clust = 0xFFFFFFFF; fs->last_clust = 0;
/* Get fsinfo if available */ if (fmt == FS_FAT32) { fs->fsi_flag = 0; fs->fsi_sector = bsect + LD_WORD(fs->win+BPB_FSInfo); if (disk_read(fs->drv, fs->win, fs->fsi_sector, 1) == RES_OK && LD_WORD(fs->win+BS_55AA) == 0xAA55 && LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 && LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) { fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); } } #endif fs->fs_type = fmt; /* FAT sub-type */ fs->id = ++Fsid; /* File system mount ID */ fs->winsect = 0; /* Invalidate sector cache */ fs->wflag = 0; #if _FS_RPATH fs->cdir = 0; /* Current directory (root dir) */ #endif #if _FS_LOCK /* Clear file lock semaphores */ clear_lock(fs); #endif
return FR_OK; }
/*-----------------------------------------------------------------------*/ /* Load a sector and check if it is an FAT Volume Boot Record */ /*-----------------------------------------------------------------------*/
static BYTE check_fs ( /* 0:FAT-VBR, 1:Any BR but not FAT, 2:Not a BR, 3:Disk error */ FATFS *fs, /* File system object */ DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ ) { if (disk_read(fs->drv, fs->win, sect, 1) != RES_OK) 這一步就用到了自己編寫的讀扇區(qū)函數(shù) /* Load boot record */ return 3; if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check record signature (always placed at offset 510 even if the sector size is >512) */ return 2;
if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ return 0; if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146) return 0;
return 1; }
//讀扇區(qū) //drv:磁盤編號(hào)0~9 //*buff:數(shù)據(jù)接收緩沖首地址 //sector:扇區(qū)地址 //count:要讀的扇區(qū)數(shù) DRESULT disk_read ( BYTE drv, /* Physical drive nmuber (0..) */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector address (LBA) */ BYTE count /* Number of sectors to read (1..255) */ ) { u8 res=0; if (!count)return RES_PARERR;//count2??üμèóú0£?·??ò·μ??2?êy′í?ó switch(drv) { case SD_CARD://SD卡的 res=SD_ReadDisk(buff,sector,count); if(res) { SD_SPI_SpeedLow(); SD_SPI_ReadWriteByte(0xff); SD_SPI_SpeedHigh(); } break; case EX_FLASH://SPI FLASH的 for(;count>0;count--) { SPI_Flash_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE); sector++; buff+=FLASH_SECTOR_SIZE; } res=0; break; case USB_DISK: res = USB_ReadDisk(buff,sector,count); //U盤的讀扇區(qū)函數(shù) default: res=1; } //處理返回值 if(res==0x00)return RES_OK; else return RES_ERROR; }
你的操作應(yīng)該是先讀取到扇區(qū)0的數(shù)據(jù)之后,才能對(duì)U盤進(jìn)行檢查,最后才是掛載文件系統(tǒng)。關(guān)鍵還是要能夠正確進(jìn)行扇區(qū)讀取。12樓對(duì)相關(guān)流程已做說(shuō)明。 如還有疑問(wèn),你也可以發(fā)郵件到我的郵箱或者直接來(lái)電咨詢。
對(duì)的,你說(shuō)得沒錯(cuò),就是需要先讀扇區(qū)0的數(shù)據(jù),現(xiàn)在就是連扇區(qū)0都沒法讀,CH375不給中斷請(qǐng)求,函數(shù)就一直在while那里等待