⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd_card.c

📁 常用的sd卡的单片机程序
💻 C
📖 第 1 页 / 共 3 页
字号:
		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 + -