转载自: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 }
View Code

相关文章: