📄 fat.c
字号:
#define PRODUCE_LOCAL_VARIABLES /*完成对变量等定义*/
#include "FAT.H"
/*#define FAT_DEBUG*/ /*调试用*/
/*#define FAT_SHOW_DATA 输出一些有用的数据*/
/*基础接口函数*/
STATIC UINT8 hard_read_sector(UINT32 sector)
{
UINT8 i;
UINT8 cc = F_RE_TIME;
while(cc)
{
i =RBC_Read(sector, 1, fat_disk_buffer);
if(i == F_OK)
return F_OK;
cc--;
}
return F_ERROR;
}/*读取一个扇区到磁盘缓存区*/
STATIC UINT8 hard_read_file_sector(UINT32 sector, UINT8 n, UINT8 offset)
{
UINT8 i;
UINT8 cc = F_RE_TIME;
while(cc)
{
i =RBC_Read(sector, n, fat_file_buffer + (offset*512));
if(i == F_OK)
return F_OK;
cc--;
}
return F_ERROR;
}/*读取一个扇区到磁盘缓存区*/
#if F_EN_WRITE ==1
STATIC UINT8 hard_write_sector(UINT32 sector)
{
UINT8 i;
UINT8 cc=F_RE_TIME;
while(cc)
{
i =RBC_Write(sector, 1, fat_disk_buffer);
if(i ==F_OK)
return F_OK;
cc--;
}
return F_ERROR;
}/*把磁盘缓存区里的数据写入U盘*/
#endif
#if F_EN_WRITE ==1
STATIC UINT8 hard_write_file_sector(UINT32 sector, UINT8 n, UINT8 offset)
{
UINT8 i;
UINT8 cc=F_RE_TIME;
while(cc)
{
i =RBC_Write(sector, n, fat_file_buffer + (offset*512));
if(i ==F_OK)
return F_OK;
cc--;
}
return F_ERROR;
}/*读取一个扇区到磁盘缓存区*/
#endif
STATIC UINT16 ushort_read_data(UINT16 i)
{
UINT16 d;
#if MCU_USE_DSP ==1
d = fat_disk_buffer[i++]; /*读出低有效字节*/
d |= (fat_disk_buffer[i]<<8); /*高有效字节*/
#else
#if MCU_USE_BIG_ENDIAN == 1 /*默认为大端否则为小端*/
((UINT8 *)&d)[1] = fat_disk_buffer[i++];
((UINT8 *)&d)[0] = fat_disk_buffer[i];
#else
((UINT8 *)&d)[0] = fat_disk_buffer[i++];
((UINT8 *)&d)[1] = fat_disk_buffer[i];
#endif
#endif
return d;
}/*从磁盘缓存区里读取一个ushort型数,i为缓冲区位置索引*/
STATIC UINT32 ulong_read_data(UINT16 i)
{
UINT32 d;
#if MCU_USE_DSP ==1
d = fat_disk_buffer[i++]; /*得到低有效字节*/
d |= (fat_disk_buffer[i++]<<8); /*得到低第二有效字节*/
d |= ((UINT32)fat_disk_buffer[i++])<<16;
d |= ((UINT32)fat_disk_buffer[i])<<24;
#else
#if MCU_USE_BIG_ENDIAN == 1
((UINT8 *)&d)[3] = fat_disk_buffer[i++];
((UINT8 *)&d)[2] = fat_disk_buffer[i++];
((UINT8 *)&d)[1] = fat_disk_buffer[i++];
((UINT8 *)&d)[0] = fat_disk_buffer[i];
#else
((UINT8 *)&d)[0] = fat_disk_buffer[i++];
((UINT8 *)&d)[1] = fat_disk_buffer[i++];
((UINT8 *)&d)[2] = fat_disk_buffer[i++];
((UINT8 *)&d)[3] = fat_disk_buffer[i];
#endif
#endif
return d;
}/*从磁盘缓存区里读取一个ulong型数,i为缓冲区位置索引*/
#if F_EN_WRITE ==1
STATIC void ushort_write_data(UINT16 i,UINT16 d)
{
#if MCU_USE_DSP ==1
fat_disk_buffer[i++] = d&0x00ff;
fat_disk_buffer[i] = (d>>8)&0x00ff;
#else
#if MCU_USE_BIG_ENDIAN == 1
fat_disk_buffer[i++] = ((UINT8 *)&d)[1];
fat_disk_buffer[i] = ((UINT8 *)&d)[0];
#else
fat_disk_buffer[i++] = ((UINT8 *)&d)[0];
fat_disk_buffer[i] = ((UINT8 *)&d)[1];
#endif
#endif
}/*写入一个ushort型数到缓冲区,i为缓冲区位置索引*/
#endif
#if F_EN_WRITE ==1
STATIC void ulong_write_data(UINT16 i,UINT32 d)
{
#if MCU_USE_DSP ==1
fat_disk_buffer[i++] = d&0x000000ff;
fat_disk_buffer[i++] = (d>>8)&0x000000ff;
fat_disk_buffer[i++] = (d>>16)&0x000000ff;
fat_disk_buffer[i] = (d>>24)&0x000000ff;
#else
#if MCU_USE_BIG_ENDIAN == 1
fat_disk_buffer[i++] = ((UINT8 *)&d)[3];
fat_disk_buffer[i++] = ((UINT8 *)&d)[2];
fat_disk_buffer[i++] = ((UINT8 *)&d)[1];
fat_disk_buffer[i] = ((UINT8 *)&d)[0];
#else
fat_disk_buffer[i++] = ((UINT8 *)&d)[0];
fat_disk_buffer[i++] = ((UINT8 *)&d)[1];
fat_disk_buffer[i++] = ((UINT8 *)&d)[2];
fat_disk_buffer[i] = ((UINT8 *)&d)[3];
#endif
#endif
}/*写入一个ulong型数到缓冲区,i为缓冲区位置索引*/
#endif
/*内部辅助函数*/
/*==============================================================================
函数名: file_name_deal
-------------------------------------------------------------------------------
参数:
-------------------------------------------------------------------------------
函数返回:
-------------------------------------------------------------------------------
函数作用:检测文件名是否合法,并初始化目录总深度(文件名不能小写,但可以汉字ANSI编码)
-------------------------------------------------------------------------------
由于考虑到汉字编码,所以没有对小写字母进行检测,使用时需要注意.
-------------------------------------------------------------------------------
==============================================================================*/
STATIC UINT8 file_name_deal(void)
{
UINT8 len;
UINT8 i;
UINT8 cc; /*用于检测文件名长度,是否是8+3格式*/
cc =1; /*此值默认为和法文件名长度*/
fat_dir_all_l =0; /*初始化目录深度初始为0*/
for(len=0; len!=FAT_CMD_BUF_LEN; len++)
{
if(fat_cmd.open.buffer[len] == 0) /*得到字符串长度*/
break;
}
for(i=0; i!=len; i++)
{
if((fat_cmd.open.buffer[i] != '.') && (fat_cmd.open.buffer[i] != '\\')
&& (fat_cmd.open.buffer[i] != '/'))
cc++;
if((fat_cmd.open.buffer[i] == '\\') || (fat_cmd.open.buffer[i] == '/'))
{
if((cc > 11) || (cc == 0))
return PARAMETER_CMD_ERR; /*文件名不合法*/
cc = 0;
fat_dir_all_l++; /*计算打开目录深度*/
}
}
if(fat_dir_all_l == 0)
{
return PARAMETER_CMD_ERR;
}
return F_OK;
}/* 文件名处理*/
/*==============================================================================
函数名: fat_read_cluster
-------------------------------------------------------------------------------
参数:(BOOL fat12_parity用于FAT12),对与FAT16/32不需要此值,bufferer_index为缓冲区里的偏移
-------------------------------------------------------------------------------
函数返回: 簇号
-------------------------------------------------------------------------------
函数作用: 从缓冲区里得到簇
-------------------------------------------------------------------------------
==============================================================================*/
STATIC UINT32 fat_read_cluster (BOOL fat12_parity, UINT16 bufferer_index)
{
UINT32 temp32;
#if F_USE_FAT32 == 1
if(fat_type_sign == F_TYPE_FAT32)
{
temp32 = ulong_read_data(bufferer_index);
temp32 &=0x0FFFFFFF;
return temp32;
}
#endif
#if F_USE_FAT16 == 1
if (fat_type_sign == F_TYPE_FAT16)
{
temp32 = (UINT32)(ushort_read_data(bufferer_index));
return temp32;
}
#endif
#if F_USE_FAT12 == 1
if(fat_type_sign == F_TYPE_FAT12)
{
UINT16 cluster;
cluster=ushort_read_data(bufferer_index);
if (fat12_parity == 0) /*簇号是是偶数取低12-bits*/
{
temp32 = (UINT32)(cluster & 0x0FFF);
return temp32;
}
else /*簇号为奇数取高12位*/
{
cluster = cluster >> 4;
temp32 = (UINT32)cluster;
return temp32;
}
}
#else
fat12_parity = 0; /*为了让编译器不产生警告*/
#endif
return F_ERROR; /*为了让编译器不产生警告*/
}
/*==============================================================================
函数名: fat12_divid_cluster
-------------------------------------------------------------------------------
参数:i 为簇离FAT开始扇区的偏移
-------------------------------------------------------------------------------
函数返回: 簇号
-------------------------------------------------------------------------------
函数作用: 用在FAT12边界扇区时读簇号
-------------------------------------------------------------------------------
==============================================================================*/
#if F_USE_FAT12 == 1
STATIC UINT16 fat12_divid_cluster(UINT16 i)
{
UINT8 t;
UINT8 t2;
UINT8 temp8;
UINT16 new_cluster;
t2 =i/SECTOR_SIZE;
if((t2==0) || (t2==3) || (t2==6) || (t2==9)) /*2^12*1.5/512=12最多占用12个扇区*/
{
t =uchar_read_data(SECTOR_SIZE-1); /*读取此簇的低4BIT*/
t &=0XF0;
t >>=4; /*取高4BIT*/
temp8=hard_read_sector(fat_start_sector + i/SECTOR_SIZE + 1);
if(temp8!=F_OK)
return F_ERROR;
temp8=uchar_read_data(0); /*读取此簇的高8BIT*/
new_cluster =(UINT16)temp8;
new_cluster <<=4;
new_cluster |=(UINT32)t;
#ifdef FAT_DEBUG
com_prints("###new_cluster0:",0);
com_send_arry(&new_cluster,4,1);
#endif
}
else
{
t = uchar_read_data(SECTOR_SIZE - 1);
temp8 = hard_read_sector(fat_start_sector + i/SECTOR_SIZE + 1);
if(temp8 != F_OK)
return F_ERROR;
temp8 =uchar_read_data(0); /*读取此簇的高8BIT*/
temp8 &=0X0F; /*取其高4BIT*/
new_cluster =(UINT16)temp8;
new_cluster <<=8;
new_cluster |=(UINT16)t;
#ifdef FAT_DEBUG
com_prints("###new_cluster1:", 0);
com_send_arry(&new_cluster, 4, 1);
#endif
}
return new_cluster;
}
#endif
/*==============================================================================
函数名: fat_write_cluster
-------------------------------------------------------------------------------
参数:
-------------------------------------------------------------------------------
函数返回:
-------------------------------------------------------------------------------
函数作用:cluster_index为连续簇的开始,number为此簇之后有多少个连续的簇.而last_cluster
-------------------------------------------------------------------------------
为下个连续开始簇或结束簇,w_mode分为构建FAT表及清空FAT表
-------------------------------------------------------------------------------
==============================================================================*/
#if F_EN_WRITE ==1
STATIC UINT8 fat_write_cluster(UINT32 cluster_index, UINT16 number, UINT32 last_cluster, BOOL w_mode)
{
UINT8 temp8;
UINT16 index;
UINT32 temp32;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -