因项目需求需要移植fatfs文件系统,参考了正点原子的战舰例程。
使用mcu为stm32f103zet6,spi的sd卡模块,8Gsd卡。例程为mini板(mcu:stm32f103rct6)的 ALIENTEK MINISTM32 实验29 FATFS文件系统实验,zet6的例程由于是sdio模式所以没有选用。
初始化
这里只初始化sd卡.e2prom部分删除了
mem_init(); //初始化内存池
//SD卡检测及初始化
while(SD_Initialize()) //检测不到SD卡
{
delay_ms(500);
}
exfuns_init(); //为fatfs相关变量申请内存
f_mount(fs[0],"0:",1); //挂载SD卡,并分配盘符“0:”
//以下不是必须
while(exf_getfree("0",&total,&free)) //得到SD卡的总容量和剩余容量
{
LCD_ShowString(4,4,200,16,16,"Fatfs Error!");
delay_ms(500);
clearTopInfo(WHITE);
delay_ms(500);
}
创建文件(.txt)
FA_CREATE_ALWAYS | FA_WRITE参数可用以下按需替换
//sprintf中的内容是从rtc中获取的时间,并放入newfilepath中。0:/是盘符(驱动器号)
sprintf(newfilepath,"0:/%04d%02d%02d_%02d%02d%02d.txt",calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);
//
res_ad=f_open(&fil_ad,newfilepath,FA_CREATE_ALWAYS|FA_WRITE);
写入文件(.txt)
由于f_write只能写入char型数据,ad采样的int型数据(或其他的int/float/double等)必须转换为char才能正确保存,否则会出现乱码。
f_write中的参数如下:
&fil_ad为f_open中使用过的路径文件;
write_buff为写的数据;
6是要写入的字节数,具体看需求,如果想写入“1234567”但给的是6则‘7’将写不进去
&bww_ad为实际写入的字节(待求证);
sprintf(write_buff,"%04d\r\n",ad_value[i]*3300/4096);
res_ad=f_lseek(&fil_ad,f_size(&fil_ad));
res_ad=f_write(&fil_ad,write_buff,6,&bww_ad);
其中f_lseek(&fil_ad,f_size(&fil_ad));函数用于把文件读写指针移动到文件末尾。
读取文件
f_open(&fil0,filepath,FA_READ); //以只读方式打开文件
for(i=0;i<232;i++) //由于知道文件里有232组数据所以设置232个循环
{
f_lseek(&fil0,i*6); //每次读取之前先移动读写指针达到读写不同数据的目的
f_gets(filedata[i],5,&fil0); //读5个字节的数据
printf("#S0000%sEN\n",filedata[i]); //通过串口发送
}
类似的,如果要读取某文件中的特定字符,比如‘A’,则可以:
f_open(&fil0,filepath,FA_READ);
while(1)
{
if(br == 0) //判断是否到达文件结尾
break; //如果是,则退出
f_read (&fil0, &readbuff, 1, br); //每次读1字节
if(readbuff == 'A') //判断是否是A
{
//todo:your code
}
}