转载自:SD卡应用总结(FatFs)
对于SD卡的应用,想必大家都尝试多。不过,很多网友恐怕只停留在实验的基础上吧。对于SD卡在文件系统下或者不带文件系统下,对SD卡的操作都是很简单的。是的,只是简单的文件读写确实不难。但是,如果每秒钟不停的写数据,而且是不停的工作,恐怕SD卡的应用就没有这么简单了吧,有时总会出现一些莫名其妙的问题。
不知道大家是否遇到过这些问题?本人开发了几个关于SD卡的项目,例如,定时拍照、定时录音等。对于这样的项目,基本上要求每一秒都在不停的写数据,而且一般一天工作好几个小时,甚至会不停的工作。在这些项目中,本人遇到太多的问题,下面把遇到的问题及解决方法与大家分享,希望有同样经验的网友一起分享一下您的经验。
--------------------------------------------------------------------------------------------------------
问题1:根目录下文件毁坏。
现象:在FatFs下可以读写文件,可在PC上无法打开目录,提示文件毁坏。
分析:通过WinHex软件打开磁盘,发现目录完全正常,但是FAT表已经毁坏,引起的原因可能是带电插拔。
解决:既然是FAT表与目录对不上,而且FAT毁坏,就是用PC修复也只会删除这些文件,对于我们的单片机来说,也没有好的解决方法,那就格式吧。
下面的代码用于判断FAT表是否和文件目录对应的上,使用的方法是:扫描FAT表,看看应用了多少簇,在通过读取FSInfo扇区的信息,看这两者是否一致。一致时为正确,不一致一般有问题。
1 /*-----------------------------------------------------------------------*/ 2 /* File system check */ 3 /*-----------------------------------------------------------------------*/ 4 5 FRESULT f_fsCheck( 6 const TCHAR *path, /* Pointer to the logical drive number (root dir) */ 7 DWORD *nclst, /* Pointer to the variable to return number of free clusters */ 8 FATFS **fatfs /* Pointer to pointer to corresponding file system object to return */ 9 ) 10 { 11 FRESULT res; 12 FATFS *fs; 13 DWORD n, clst, sect, stat; 14 UINT i; 15 BYTE fat, *p; 16 17 /* Get drive number */ 18 res = chk_mounted(&path, fatfs, 0); 19 fs = *fatfs; 20 if (res == FR_OK) 21 { 22 /* Get number of free clusters */ 23 fat = fs->fs_type; 24 n = 0; 25 if (fat == FS_FAT12) 26 { 27 clst = 2; 28 do { 29 stat = get_fat(fs, clst); 30 if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } 31 if (stat == 1) { res = FR_INT_ERR; break; } 32 if (stat == 0) n++; 33 } while (++clst < fs->n_fatent); 34 } 35 else 36 { 37 clst = fs->n_fatent; 38 sect = fs->fatbase; 39 i = 0; p = 0; 40 BYTE cnt = 0; 41 do{ 42 if(!i) 43 { 44 res = move_window(fs, sect++); 45 if (res != FR_OK) break; 46 p = fs->win; 47 i = SS(fs); 48 } 49 if (fat == FS_FAT16) 50 { 51 if (LD_WORD(p) == 0) n++; 52 p += 2; i -= 2; 53 } 54 else 55 { 56 if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) 57 { 58 if (++cnt > 10) // 连续10个空簇,退出 59 { 60 break; 61 } 62 } 63 else 64 { 65 n++; 66 cnt = 0; 67 } 68 p += 4; i -= 4; 69 } 70 } while (--clst); 71 } 72 73 if (fs->last_clust > (n+10)) 74 { 75 res = FR_INT_ERR; 76 } 77 } 78 LEAVE_FF(fs, res); 79 }