📄 sd_card.c
字号:
p[19] = p[17];
p[20] = p[21] = 0x00;
p[22] = (char)pcf_wtime;
p[23] = (char)(pcf_wtime>>8);
p[24] = (char)pcf_wdate;
p[25] = (char)(pcf_wdate>>8);
p[26] = (char)dir_lastc;
p[27] = (char)(dir_lastc>>8);
p[28] = p[29] = p[30] = p[31] = 0x00;
/* 写".."目录,父目录 */
i = 32;
p[i] = p[i+1] = 0x2E;
for(num=2;num<11;num++)
p[i+num] = 0x20;
p[i+11] = 0x10;
p[i+12] = 0x00;
p[i+13] = pcf_b10ms; //....pcf_b10ms 位于pcf8563程序中
p[i+14] = (char)pcf_wtime; //....pcf_wtime...
p[i+15] = (char)(pcf_wtime>>8);
p[i+16] = (char)pcf_wdate;
p[i+17] = (char)(pcf_wdate>>8);
p[i+18] = p[i+16];
p[i+19] = p[i+17];
p[i+20] = p[i+21] = 0x00;
p[i+22] = (char)pcf_wtime;
p[i+23] = (char)(pcf_wtime>>8);
p[i+24] = (char)pcf_wdate;
p[i+25] = (char)(pcf_wdate>>8);
//p[i+26] = (char)dir_lastc;
//p[i+27] = (char)(dir_lastc>>8);
p[i+26] = p[i+27] = 0x00;
p[i+28] = p[i+29] = p[i+30] = p[i+31] = 0x00;
/* 清零p[64]~p[511] */
for(i+=32; i<512; i++)
p[i] = 0;
sd_write_block(sd_address,p); //写第1扇区
/* 写该簇后面的扇区,内容为0 */
for(i=0; i<512; i++)
p[i] = 0;
for(num=1;num<sd_sc;num++)
{
sd_address += 512;
sd_write_block(sd_address,p);
}
}
}
/*******************************************************************************/
/* Function : check_name */
/* Input : int index -- 文件名第一个字符:sd_buffer[index] */
/* Output : char -- 返回逻辑值 */
/* Description : 文件名相同返回1,否则返回0 */
/*******************************************************************************/
char check_name(int index)
{
char *p1,*p2;
int i = 0;
p1 = dir_name;
p2 = sd_buffer;
while((p1[i]==p2[index+i])&&(i<=10))
i++;
if(i>10)
return 1;
else
return 0;
}
/*******************************************************************************/
/* Function : chars_to_int */
/* Input : char low_byte -- 低位字节 */
/* char high_byte -- 高位字节 */
/* Output : unsigned int -- 两字节合并后的字 */
/* Description : 将两个字符型合成一个无符号的整型 */
/*******************************************************************************/
unsigned int chars_to_int(char low_byte, char high_byte)
{
unsigned int low;
unsigned int high;
low = (unsigned int)low_byte;
high = (unsigned int)high_byte;
//high左移8位,把high_byte移到高8位,低8位补0
high <<= 8;
//low高8位清零,低8位为low_byte
low &= 0x00ff;
high = high | low;
return high;
}
/*******************************************************************************/
/* Function : ints_to_long */
/* Input : unsigned int low_int -- 低位字 */
/* unsigned int high_int -- 高位字 */
/* Output : unsigned long -- 合并后的长整型 */
/* Description : 将两个整型合成长整型 */
/*******************************************************************************/
unsigned long ints_to_long(unsigned int low_int, unsigned high_int)
{
unsigned long low;
unsigned long high;
//low高16位清零,低16位为low_int
low = (unsigned long)low_int;
low &= 0x0000ffff;
//high高16位为high_int,低16位为0
high = (unsigned long)high_int;
high <<= 16;
high |= low;
return high;
}
/*******************************************************************************/
/* Function : find_lastc */
/* Input : unsigned int firstc -- 文件首簇簇号 */
/* Output : unsigned int -- 文件末簇簇号 */
/* Description : 根据文件的首簇簇号找到末簇簇号 */
/*******************************************************************************/
unsigned int find_lastc(unsigned int firstc)
{
unsigned long address;
unsigned int high,low;
unsigned int rvalue;
unsigned int temp = 0xffff;
char *p = sd_buffer; //单块读出的数据放在sd_buffer[0]~sd_buffer[511]中
rvalue = firstc;
while(1)
{
low = rvalue;
low &= 0x00ff; //low为其低字节
high = rvalue;
high >>= 8;
high &= 0x00ff; //右移8位,得到其高8位字节
//登记项在FAT表中按顺序排列,每个登记项占两个字节,high就代表该簇登记项位于FAT表
//中的哪个扇区,sd_fat1_addr+high*512就代表该簇所在扇区的物理地址(扇区首地址)
if(high!=temp)
{
temp = high;
address = sd_fat1_addr + (unsigned long)high*512;
sd_read_block(address,p);
}
//读簇登记项内容,如果其值大于等于最大簇号,表示该簇为文件最后一簇
//否则其内容为下一簇号
if(chars_to_int(p[low*2],p[low*2+1])>=sd_mcn)
return rvalue;
else
rvalue = chars_to_int(p[low*2],p[low*2+1]);
}
}
/*******************************************************************************/
/* Function : find_newc */
/* Input : none */
/* Output : unsigned int */
/* Description : 找到一个空簇并占用(写0xFFFF),返回该簇的簇号 */
/* 若没有空簇则返回SD_NO_SPACE */
/*******************************************************************************/
unsigned int find_newc(void)
{
unsigned long address;
unsigned int rvalue;
char *p = sd_buffer; //单块读出的数据放在sd_buffer[0]~sd_buffer[511]中
unsigned int num;
char flag = 1;
address = sd_fat1_addr+(unsigned long)fat_offset*512;
while(fat_offset<sd_sf)
{
sd_read_block(address,p);
num =0;
while((num<512)&flag)
{
if(chars_to_int(p[num],p[num+1])==0)//登记项为0,表示该簇未占用
{
flag = 0;
}
else
num = num + 2;
}
if(flag == 0) break;
fat_offset++;
address += 512; //读下一扇区
}
if(fat_offset>=sd_sf)
return SD_NO_SPACE; //没有找到空簇,返回SD_NO_SPACE
p[num] = 0xff;
p[num+1] = 0xff; //占用该簇
sd_write_block(address,p); //写进FAT表
//FAT表每扇区有256个簇登记项,每个簇登记项占两字节
rvalue = fat_offset*256+num/2;
return rvalue;
}
/*******************************************************************************/
/* Function : find_nextc */
/* Input : unsigned int former -- 当前簇簇号 */
/* Output : unsigned int -- 下一簇簇号 */
/* Description : 根据文件当前簇簇号找到下一簇簇号 */
/*******************************************************************************/
unsigned int find_nextc(unsigned int former )
{
unsigned long address;
unsigned int high,low;
unsigned int rvalue;
char *p = sd_buffer; //单块读出的数据放在sd_buffer[0]~sd_buffer[511]中
rvalue = former;
low = rvalue;
low &= 0x00ff; //low为其低字节
high = rvalue;
high >>= 8;
high &= 0x00ff; //右移8位,得到其高8位字节
//登记项在FAT表中按顺序排列,每个登记项占两个字节,high就代表该簇登记项位于FAT表
//中的哪个扇区,sd_fat1_addr+high*512就代表该簇所在扇区的物理地址(扇区首地址)
address = sd_fat1_addr + (unsigned long)high*512;
sd_read_block(address,p);
rvalue = chars_to_int(p[low*2],p[low*2+1]);
return rvalue;
}
/*******************************************************************************/
/* Function : extend_cluster */
/* Input : unsigned int old -- 原有的末簇簇号 */
/* Output : unsigned int -- 新的末簇簇号 */
/* Description : 在FAT表中找到一个空簇并占用作为文件新的末簇 */
/*******************************************************************************/
unsigned int extend_cluster(unsigned int old)
{
unsigned long address;
unsigned int high,low;
unsigned int rvalue;
char *p = sd_buffer; //单块读出的数据放在sd_buffer[0]~sd_buffer[511]中
rvalue = old;
low = rvalue;
low &= 0x00ff; //low为其低字节
high = rvalue;
high >>= 8;
high &= 0x00ff; //右移8位,得到其高8位字节
//登记项在FAT表中按顺序排列,每个登记项占两个字节,high就代表该簇登记项位于FAT表
//中的哪个扇区,sd_fat1_addr+high*512就代表该簇所在扇区的物理地址(扇区首地址)
address = sd_fat1_addr + (unsigned long)high*512;
sd_read_block(address,p);
rvalue = find_newc(); //找到一个空簇,并占用作为新的末簇
p[low*2] = (char)rvalue; //簇号的低字节
p[low*2+1] = (char)(rvalue>>8); //簇号的高字节
sd_write_block(address,p); //写进FAT表
return rvalue;
}
/*******************************************************************************/
/* Function : clear_cluster */
/* Input : unsigned int cluster -- 待清零簇的簇号 */
/* Output : none */
/* Description : 清空一个簇,写入0 */
/*******************************************************************************/
void clear_cluster(unsigned int cluster)
{
unsigned long address;
int i;
char *p = sd_buffer; //单块写的数据放在sd_buffer[0]~sd_buffer[511]中
address = cs_to_addr(cluster,0);
for(i=0;i<512;i++)
p[i] = 0;
for(i=0;i<sd_sc;i++)
{
sd_write_block(address,p);
address += 512;
}
}
/*******************************************************************************/
/* Function : cs_to_addr */
/* Input : unsigned int cluster -- 簇号 */
/* char sector -- 扇区号 */
/* Output : unsigned long -- 物理地址 */
/* Description : 把簇扇区坐标转换为SD卡的物理地址 */
/*******************************************************************************/
unsigned long cs_to_addr(unsigned int cluster,char sector)
{
unsigned long address;
char sc = sd_sc;
address = sd_data_addr; //DATA(用户数据区)首地址
//因为起始簇号为0002,所以加上(簇号-2)*SC*512+扇区号*512
address += (unsigned long)(cluster-2) * (unsigned long)sc * 512;
address += (unsigned long)sector * 512;
return address;
}
/*******************************************************************************/
/* Function : bcd_to_ascii */
/* Input : char BCD_code -- BCD码 */
/* Output : unsigned int -- 转换后的ASCII码 */
/* Description : 将BCD码转换为ASCII码, */
/* 低字节为BCD码的高4位的ASCII码,高字节为BCD码的低4位的ASCII码 */
/*******************************************************************************/
unsigned int bcd_to_ascii(char BCD_code)
{
unsigned int rvalue;
char c1,c2;
c1 = BCD_code;
c1 &= 0xf0; //取BCD_code的高四位
c1 >>= 4;
c1 &= 0x0f; //将高4位移至低4位
if(c1 >= 10)
c1 += 55; //对应ASCII码的A~F
else
c1 += 48; //对应ASCII码的0~9
c2 = BCD_code & 0x0f; //取BCD_code的低四位
if(c2 >= 10)
c2 += 55;
else
c2 += 48;
rvalue = chars_to_int(c1,c2);
return rvalue;
}
/*******************************************************************************/
/* Function : ascii_to_bcd */
/* Input : char code1,code2 -- ASCII码 */
/* Output : char -- 转换后的BCD码 */
/* Description : 将ASCII码转换为BCD码,ASCII码的范围必需是0~9和A~F */
/* code1转换的BCD码储存在返回值的高4位,code2的BCD码在返回值的低4位 */
/*******************************************************************************/
char ascii_to_bcd(char code1,char code2)
{
char rvalue;
if((code1>=48)&&(code1<=57))
code1 -= 48; //对应ASCII码的0~9,转为BCD码
else
code1 -= 55; //对应ASCII码的A~F,转为BCD码
if((code2>=48)&&(code2<=57))
code2 -= 48; //对应ASCII码的0~9,转为BCD码
else
code2 -= 55; //对应ASCII码的A~F,转为BCD码
rvalue = code1;
rvalue <<= 4; //code1位于高4位
rvalue |= code2; //code2位于低4位
return rvalue;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -