51单片机读写SD卡程序,使用FAT文件系统

  • b9_624066
    了解作者
  • C/C++
    开发工具
  • 71.2KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-02-24 15:41
    上传日期
51单片机读写SD卡程序,使用FAT文件系统,51单片机也可以有海量存储了
51单片机读写SD卡程序,使用FAT文件系统
  • SDCard
  • SD.h
    3.3KB
  • SD.LST
    10.9KB
  • SD_Opt.Bak
    1.1KB
  • main.OBJ
    7.3KB
  • FAT.OBJ
    25.5KB
  • SD_Uv2.Bak
    2.2KB
  • SD.c.bak
    4.7KB
  • SD.M51
    34.8KB
  • SD.bak
    3.2KB
  • SD.Opt
    1.4KB
  • MAIN.bak
    1.7KB
  • SD.Uv2
    2.2KB
  • SD.c
    4.6KB
  • main.c
    1.5KB
  • SD.h.bak
    3.3KB
  • FAT.h
    689B
  • FAT.LST
    14.1KB
  • STARTUP.LST
    11.4KB
  • SD
    44.6KB
  • SD.plg
    164B
  • main.LST
    4KB
  • SD.OBJ
    16.7KB
  • main.c.bak
    1.5KB
  • STARTUP.A51
    5KB
  • FAT.h.bak
    679B
  • FAT.bak
    4.8KB
  • FAT.c
    8.3KB
  • FAT.c.bak
    8.3KB
  • SD.hex
    15.4KB
  • STARTUP.OBJ
    749B
  • SD.lnp
    100B
内容介绍
#include "SD.h" #include "FAT.h" //FAT系统信息 unsigned long FATOffset; //FAT表的起始绝对扇区号 unsigned long RDTOffset; //RDT表的起始绝对扇区号 unsigned long DataOffset; //Data区的起始绝对扇区号 unsigned int MaxCluster; //最大的簇序号,FAT16 unsigned int RDTEntryNum; //根目录项数 unsigned char ClusterSize; //每簇扇区数 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //将一个16位数按字节倒序 void Swap16(unsigned int *Var) { *Var = ((*Var & 0xFF00)>>8 | (*Var & 0x00FF)<<8); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //将一个32位数按字节倒序 void Swap32(unsigned long *Var) { *Var = ((*Var & 0xFF000000)>>24 | (*Var & 0x00FF0000)>>8 | (*Var & 0x0000FF00)<<8 | (*Var & 0x000000FF)<<24); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //读取并计算SD卡文件系统信息,返回0x00时操作成功,0xFF时出错。 unsigned char InitFAT() { //FAT文件系统参数 unsigned long RelSector; unsigned long TotalSector; unsigned int ReservedSector; unsigned char FATNum; unsigned int FATSize; //初始化SD卡 if(InitSD()!=0x00) return 0xFF; //读取FAT文件系统参数 if(0x00 != ReadSectorPartial(0, 454, 4, (unsigned char *)&RelSector)) return 0xFF; Swap32(&RelSector); if(0x00 != ReadSectorPartial(0, 458, 4, (unsigned char *)&TotalSector)) return 0xFF; Swap32(&TotalSector); if(0x00 != ReadSectorPartial(RelSector, 14, 2, (unsigned char *)&ReservedSector)) return 0xFF; Swap16(&ReservedSector); if(0x00 != ReadSectorPartial(RelSector, 13, 1, &ClusterSize)) return 0xFF; if(0x00 != ReadSectorPartial(RelSector, 16, 1, &FATNum)) return 0xFF; if(0x00 != ReadSectorPartial(RelSector, 17, 2, (unsigned char *)&RDTEntryNum)) return 0xFF; Swap16(&RDTEntryNum); if(0x00 != ReadSectorPartial(RelSector, 22, 2, (unsigned char *)&FATSize)) return 0xFF; Swap16(&FATSize); //计算FAT系统信息 FATOffset = RelSector + ReservedSector; RDTOffset = FATOffset + FATNum * FATSize; DataOffset = RDTOffset + (RDTEntryNum * 32) / 512; MaxCluster = (unsigned int)((TotalSector + 1 - DataOffset) / ClusterSize + 1); return 0x00; //初始化成功 } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //在SD卡根目录下查找指定文件,返回0x00时操作成功,0xFF时出错。 //参数pFile为文件结构体指针;pFileName为要查找的文件名。 //文件名长11字节;前8个为文件名,不足8字节的在后面补空格;后3字节为文件后缀;所有字符为ASCII码大写字符。 unsigned char FileOpen(PFILE pFile, char *pFileName) { unsigned int Entry, EntrySecOffset; unsigned long EntrySector; unsigned char i; idata char FileName[11]; for(Entry=0; Entry<RDTEntryNum; Entry++) //在RDT表中搜索各个Entry { //计算Entry的起始位置 EntrySector = (Entry * 32) / 512 + RDTOffset; EntrySecOffset = (Entry * 32) % 512; //读取Entry的前11字节 if(0x00 != ReadSectorPartial(EntrySector, EntrySecOffset, 11, FileName)) return 0xFF; //比较文件名 for(i=0; i<11; i++) { if(FileName[i] != *(pFileName+i)) break; } if(i == 11) break; //文件名匹配,找到文件 } if(Entry == RDTEntryNum) return 0xFF; //没有找到该文件 //填充FILE结构 if(0x00 != ReadSectorPartial(EntrySector, EntrySecOffset+26, 2, (unsigned char *)&(pFile->FileHead))) return 0xFF; Swap16(&(pFile->FileHead)); if(0x00 != ReadSectorPartial(EntrySector, EntrySecOffset+28, 4, (unsigned char *)&(pFile->FileSize))) return 0xFF; Swap32(&(pFile->FileSize)); pFile->CurPos = 0; return 0x00; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //定位文件当前读写位置,返回0x00时操作成功,0xFF时出错。 //参数pFile为文件结构体指针;Origin为定位参考点;Offset为重定位的偏移量。 unsigned char FileSeek(PFILE pFile, long Offset, unsigned char Origin) { long tmp; switch(Origin) { case SEEK_SET : tmp = 0; break; case SEEK_CUR : tmp = pFile->CurPos; break; case SEEK_END : tmp = pFile->FileSize; break; default : return 0xFF; } tmp += Offset; if(tmp < 0 || tmp > pFile->FileSize) return 0xFF; pFile->CurPos = tmp; return 0x00; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //读取文件内容,返回0x00时操作成功,0xFF时出错。 //参数pFile为文件结构体指针;pBuf为读取缓冲区;ReadBytes为要读取的字节数。 unsigned char FileRead(PFILE pFile, char *pBuf, unsigned int ReadBytes) { unsigned long Sector; unsigned int Offset; unsigned int i, Cluster = pFile->FileHead; if(((pFile->CurPos) + ReadBytes) > (pFile->FileSize)) return 0xFF; //出错,越过文件边界 //计算文件当前读写位置所在的扇区和扇区内偏移量 for(i=0; i < (pFile->CurPos)/(512 * ClusterSize); i++) { if(0x00 != ReadSectorPartial((FATOffset + (Cluster / 256)), ((Cluster % 256) * 2), 2, (unsigned char *)&Cluster)) return 0xFF; Swap16(&Cluster); if((Cluster > 0xFFF7) && (i < (pFile->CurPos)/(512 * ClusterSize))) return 0xFF; //出错,已到达文件结束扇区 } Sector = DataOffset + (Cluster - 2) * ClusterSize + ((pFile->CurPos) % (512 * ClusterSize)) / 512; Offset = (pFile->CurPos) % 512; //读取文件 while(ReadBytes > 0) { if((ReadBytes + Offset) <= 512) { if(0x00 != ReadSectorPartial(Sector, Offset, ReadBytes, pBuf)) return 0xFF; pFile->CurPos += ReadBytes; ReadBytes = 0; } else { if(0x00 != ReadSectorPartial(Sector, Offset, (512 - Offset), pBuf)) return 0xFF; pFile->CurPos += (512 - Offset); ReadBytes -= (512 - Offset); } //跳到下一扇区 if((++Sector - DataOffset) % ClusterSize == 0) { if(0x00 != ReadSectorPartial((FATOffset + (Cluster / 256)), ((Cluster % 256) * 2), 2, (unsigned char *)&Cluster)) return 0xFF; Swap16(&Cluster); Sector = DataOffset + (Cluster - 2) * ClusterSize; } Offset = 0; } return 0x00; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //写文件当前位置所在的扇区,返回0x00时操作成功,0xFF时出错。 //参数pFile为文件结构体指针;pBuf为写缓冲区。 //写文件操作以扇区为单位进行,文件当前位置的低9位被忽略;写缓冲区大小为512字节。 //如果只想修改当前扇区的一部分内容,必须将欲修改扇区的内容读到缓冲区,修改后再整扇区回写。 //如果文件长度不是512的整倍数,则在写文件最后一个扇区时将超出文件范围,这种情况下不报错。 //此操作不会修改文件当前位置。 unsigned char FileWrite(PFILE pFile, char *pBuf) { unsigned long Sector; unsigned int i, Cluster = pFile->FileHead; if((pFile->CurPos / 512) > (pFile->FileSize / 512)) return 0xFF; //出错,越过文件边界 //计算文件当前读写位置所在的扇区 for(i=0; i < (pFile->CurPos)/(512 * ClusterSize); i++) { if(0x00 != ReadSectorPartial((FATOffset + (Cluster / 256)), ((Cluster % 256) * 2), 2, (unsigned char *)&Cluster)) return 0xFF; Swap16(&Cluster); if((Cluster > MaxCluster) && (i < (pFile->CurPos)/(512 * ClusterSize))) return 0xFF; //出错,越出文件结束扇区 } Sector = DataOffset + (Cluster - 2) * ClusterSize + ((pFile->CurPos) % (512 * ClusterSize)) / 512; return WriteSector(Sector, pBuf); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //浏览SD卡根目录(返回根目录下指定的第几个文件的文件名),返回0x00时操作成功,0xFF时出错。 //参数SN指定要查找第几个有效文件;pFileName指向找到的有效文件名。 //文件名长11字节;前8个为文件名,不足8字节的在后面补空格;后3字节为文件后缀;所有字符为ASCII码大写字符。 unsigned char DirBrowse(unsigned char SN, char *pFileName) { unsigned int Entry, EntrySecOffset; unsigned long EntrySector; for(Entry=0; Entry<RDTEntryNum; Entry++) //在RDT表中搜索各个Entry { //计算Entry的起始位置 EntrySector
评论
    相关推荐
    • 单片机课件
      能够帮助同学们快速的了解单片机并对于单片机的一些设计程序有一定的认知
    • 爱上单片机
      一本电子爱好者都能看懂,会边看边笑的单片机入门书籍,作者杜洋曾在《无线电》上发表过“趣味单片机制作专题”、“单片机编程魔法学校”等深受读者喜爱、让无数单片机入门者热血沸腾的系列文章。本书通过生动的语言...
    • 单片机资料
      内含30个单片机应用开发的资料,包括配套单片机入门PPT。
    • 单片机课件
      单片机课的课件,对单片机的基础进行了全面的概述,也有非常精细的指导。
    • 单片机工具
      单片机工具 供单片机学习使用 免费资源 日后还会有更多资源 请联系我
    • 单片机课件
      单片机课件 ppt文件格式 介绍了单片机的结构、程序设计、定时器、中断等
    • 单片机教程
      这是一个单片机的教程,可以用于初次学习单片机的人学习。
    • 单片机课件
      单片机的课件及例题, 单片机的课件及例题, 单片机的课件及例题, 单片机的课 件及例题,
    • 单片机入门
      很好的单片机学习资源,入门比较好适合对单片机的学习有兴趣的人,而且是名校的精彩讲解,
    • 爱上单片机
      《爱上单片机》本书是一本电子爱好者都能看懂,会边看边笑的单片机入门书籍,作者杜洋曾在《无线电》上发表过“趣味单片机制作专题”、“单片机编程魔法学校”等深受读者喜爱、让无数单片机入门者热血沸腾的系列文章...