用文件系统获取SD卡总容量 已用容量 可用容量
先看结果吧。下面分别开发板上实现的效果和电脑上插上SD卡的效果截图。
怎么样?数字丝毫不差吧?
买了开发板的朋友,还等什么,猛击下面的链接下载源程序吧。拿出你的SD卡试试,我只有2G的和8G的卡,都没有问题,按道理最大支持32G的卡。哪位朋友有64G以上的卡,试完结果以后请在留言框里面告知我一声结果,瑞生在这里先谢了。
点击下载源程序:模拟WIN7显示SD卡容量
下面详解实现原理:
程序移植目前为止的最新版FatFs(0.10c版本)。挂载了文件系统以后,总的容量就已经知道了,然后再执行一下f_getfree()函数,可用容量就知道了。总的容量减去可用容量就是已用容量,用已用容量和总容量就可以做仿WIN7电脑硬盘的“已使用进度条”了。
原理听起来很简单吧。
获取容量的函数如下所示:
BYTE GET_FreeCAP(void) { FATFS fs; FATFS *pfs; DWORD fre_clust; BYTE res; pfs=&fs; f_mount(&fs, "" , 1); // 挂载文件系统 res = f_getfree("", &fre_clust, &pfs); if (res) return res; // 如果f_getfree函数执行错误,返回错误值 else // 如果成功获得容量 { TOT_SIZE = (pfs->n_fatent - 2) * pfs->csize/2; //总容量 单位byte FRE_SIZE = fre_clust * pfs->csize/2; // 可用容量 单位byte } f_mount(0, 0, 1); //卸载文件系统 return 0; }
FatFs 0.10版本的挂载文件系统函数f_mount较之前的有变化,参数由原来的2个变为3个,路径不能直接写0了,要写成””或者”0:”,最后一个参数1,表示是否立即挂载文件系统,1就立即挂载,0是稍后挂载。
TOT_SIZE和FRE_SIZE是定义的全局变量,用来放总容量和可用容量,注意最后的单位是字节(byte),如果要转换成MB,就要除以1024,如果要转换成GB,就再除以1024。
进度条实现起来也简单,就是“已用容量”占“总容量”的百分比。
主函数如下所示:
int main() { double fraction, integer; double temp; uint16_t jindu=0; LCD_Init(); // 液晶显示器初始化 W25Q16_Init(); // W25Q16初始化 LCD_Clear(WHITE); // 全屏显示白色 /*----- 检测并初始化SD卡 ------*/ while(SD_Init()!=0)//循环检测SD卡是否存在 { LCD_ShowString(20,60,"没有检测到SD卡"); delay_main(); } GET_FreeCAP(); LCD_ShowString(20,10,"可移动磁盘:"); LCD_DrawRectage(20,30,220,50,GRAY); // 画进度条边框 LCD_Fill(21 ,31 ,219,49,LGRAY); // 填充底色 jindu = (TOT_SIZE-FRE_SIZE)*200/TOT_SIZE; LCD_Fill(21 ,31 ,jindu+21,49,DARKBLUE); // 填充已用进度 POINT_COLOR = BLACK; // 计算可用容量 temp = (double)FRE_SIZE/1024/1024; fraction = modf(temp, &integer); // 结果保留2位,观察第3位大于5就进1,小于5就不进1 if(((uint16_t)(fraction*1000)%10)<5) fraction = fraction*100; else fraction = fraction*100 + 1; LCD_ShowNum(20,55,integer,3); // 这个显示数字,会把前面的0去掉 LCD_ShowChar(44,55,'.'); LCD_ShowNumDZ(52,55,fraction,2); // 这个显示数字,不会去掉前面的0, LCD_ShowString(68,55,"GB可用,"); //计算总容量 LCD_ShowString(132,55,"共 GB"); temp = (double)TOT_SIZE/1024/1024; fraction = modf(temp, &integer); // 结果保留2位,观察第3位大于5就进1,小于5就不进1 if(((uint16_t)(fraction*1000)%10)<5) fraction = fraction*100; else fraction = fraction*100 + 1; LCD_ShowNum(148,55,integer,3); LCD_ShowChar(172,55,'.'); LCD_ShowNumDZ(180,55,fraction,2); while(1) { ; } }
程序中用到了modf函数,用来提取转换成GB以后的小数和整数。使用此函数,需要调用头文件math.h。例如一个数12.345,利用modf提取出小数和整数以后,整数为12,小数为0.345,所以程序中由把小数乘了100,结果保留2位小数,为了结果准确,判断小数点后面的第三位,采用四舍五入,来保留2位小数点后面的数。