stm32测试SDHC卡驱动
0赞之前已经对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]);
这样,就将连续的数据填入到结构体中了。然后将一些重要的数据显示出来。
可以看出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"); } }
从串口读取的数据
写数据也是成功的。
最后就测试一下擦除了。
主体代码:
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.然后去读取擦除扇区的值。
可以看出,数据都是0,表明数据擦除成功。
通过这样的测试,说明,我们写的SDHC卡驱动,是可以使用的。其实还有些其他操作,比如读取SD卡的内部的一些寄存器的值,这些都没有介绍,不过道理也是一样的,发送命令,读取数据即可
SD卡驱动,重要的要掌握SD卡的初始化,SD卡数据读取和数据写入,数据擦除。有了这些,就可以操作我们的SD卡。