weiqi7777

stm32测试SDHC卡驱动

0
阅读(3294)

之前已经对SDHC卡的底层驱动已经写好了函数,接下来就利用写好的函数来测试队SDHC卡的驱动。

SD2.0标准规定SDHC卡必须使用FAT32文件系统。所以这里首先是提取文件系统信息。有了解过FAT32文件系统的话,知道文件系统的信息都是存在0扇区的,所有,首先是将0扇区的数据给读取出来,然后进行处理。

首先是定义BPB的结构体,存储FAT32文件系统的相干信息。


#pragma pack(1)
typedef struct
{
   __IO uint16_t  byte_per_sector;	    //0B
   __IO uint8_t   sector_per_cluster;	//0D
   __IO uint16_t  reserved_sector;		//0E
   __IO uint8_t   number_fat;			//10
   __IO uint16_t  no_use_1;				//11
   __IO uint16_t  no_use_2;				//13
   __IO uint8_t   media_descriptor;		//15
   __IO uint16_t  no_use_3;				//16
   __IO uint16_t  sector_per_trark;		//18
   __IO uint16_t  number_head;			//1A
   __IO uint32_t  hidden_sector;			//1C
   __IO uint32_t  all_sector;			//20
   __IO uint32_t  sector_fat_use;		//24
   __IO uint32_t  no_use_4;				//28
   __IO uint32_t  root_start_cluster;  	//2C
}fat_32;
#pragma pack()


这里要注意,要使用#pragma pack(1) ,使结构体以一个字节对齐。关于对齐,可以自行百度。这里如果不以一个字节对齐的话,结果是 不对的。

主体代码;


fat_32  *fat_file;
   uint8_t response;
   uint16_t i=0;
   periph_init();
   printf("hello world!!!!\n");
   while(1)
   {
	  response = SD_reset();
	  if(response == RESET_SUCCESS)
	    break;
	  i++;
	  if(i==20)
	  {
		printf("初始化失败\n");
		i = 0;
	  } 
	  delay_ms(5);
   }
     printf("初始化成功\n");
     delay_ms(200);
	 response = SD_read_sector_data(0,SD_data,1); 
      for(i=0; i<512; i++)
		 {
		    if(i%16 == 0 && i != 0)
			   printf("\n");
			if(i%8 == 0 && i != 0 && i%16 !=0)
			   printf("   ");
			printf("%2x ",SD_data[i]);			
		 } 
		 printf("\n");

	fat_file = (fat_32 *)(&SD_data[0x0b]);

	printf("扇区字节数:%d		",fat_file->byte_per_sector);
	printf("每簇扇区数:%d\n",fat_file->sector_per_cluster);
    printf("保留扇区数:%d		",fat_file->reserved_sector);
	printf("FAT表份数:%d		",fat_file->number_fat);
	printf("介质类型:%x\n",fat_file->media_descriptor);
	printf("磁盘总扇区数:%d		",fat_file->all_sector);
	printf("FAT表占用扇区数:%d\n",fat_file->sector_fat_use);
	printf("根目录入口簇号:%d\n",fat_file->root_start_cluster);


首先是定义了一个fat32的结构体指针。然后读取扇区0的数据。然后将读取的512字节数据填入到结构体中。这里因为数据是依次的填入到结构体中,所以这里使用一个指针的技巧。

fat_file = (fat_32 *)(&SD_data[0x0b]);

这样,就将连续的数据填入到结构体中了。然后将一些重要的数据显示出来。

clip_image001

可以看出0扇区就是DBR,从11数据开始就是BPB数据。对BPB的数据进行处理,就可以得到FAT32的相关信息了。

然后是测试写数据。首先,我在SD卡中,放了一个txt文件,里面的内容是沁园春·雪。通过winhex软件,查看,得知,这个文件的内容在30304扇区,因为数据比较小,只占着一个扇区。所以我就将这个扇区的数据给读取出来,然后在写到其他扇区去(这里写入的扇区为9198825和9198826),然后在读取这两个扇区,看看数据是否正确。

主体代码:


response = SD_read_sector_data(30304,SD_data,1);
   for(i=0; i<512; i++)
      SD_data[512+i] = SD_data[i];
   printf("测试连续写扇区,写两个\n");
   response = SD_write_sector_data(9198825,SD_data,2); 
  if(response == WRITE_SECTOR_SUCCESS)
  {
      printf("写入数据成功,写入扇区为9198825,共两个\r\n");
	  for(i=0; i<1024; i++)
          SD_data[i] = 5;
	  response = SD_read_sector_data(9198825,SD_data,2);
	 printf("读取扇区9198825和9198826的数据\n");
	  if(response == READ_SECTOR_SUCCESS) 
	  {
		 for(i=0; i<1024; i++)
		 {
		   	 printf("%c",SD_data[i]);
			 if(i==512)
			    printf("\n");
		 } 
		 printf("\n");
		 printf("读取数据成功\n");
	  }
   }


从串口读取的数据

clip_image002

写数据也是成功的。

最后就测试一下擦除了。

主体代码:


 response = SD_erase_sector(9198825, 9198826);
   if(response == ERASE_SECTOR_SUCCESS)
   {
	  printf("擦除数据成功");
	  for(i=0; i<1024; i++)
          SD_data[i] = 1;
	  SD_read_sector_data(9198825,SD_data,2);  
      for(i=0; i<1024; i++)
		 {
		    if(i%16 == 0 && i != 0)
			   printf("\n");
			if(i%8 == 0 && i != 0 && i%16 !=0)
			   printf("   ");
			printf("%2x ",SD_data[i]);			
		 } 
		 printf("\n");
   }
   else
       printf("擦除数据不成功");

首先是执行擦除函数,然后将数组给清1.然后去读取擦除扇区的值。

clip_image003

可以看出,数据都是0,表明数据擦除成功。

通过这样的测试,说明,我们写的SDHC卡驱动,是可以使用的。其实还有些其他操作,比如读取SD卡的内部的一些寄存器的值,这些都没有介绍,不过道理也是一样的,发送命令,读取数据即可

SD卡驱动,重要的要掌握SD卡的初始化,SD卡数据读取和数据写入,数据擦除。有了这些,就可以操作我们的SD卡。