环境准备
硬件:AC781X demo板, SD卡,卡套
软件: Keil5.2.3
因为AC781X不支持SDIO,所以我们要采用SPI方式与SD卡通信,SPI有4线,加上电源线总共六根线,下图是我焊好的接线(千万不要直接在SD卡上焊,不然SD卡就焊废了)
1,首先从网上下载最新的FATFS文件系统源码http://elm-chan.org/fsw/ff/00index_e.html,本贴用的是R0.13c版本
2,新建一个keil工程,并在工程下新建一个FATfs文件夹,将下载的文件解压到该文件夹下
3,按官方的文档,我们只需要移植实现diskio.c中的函数即可;这里,我们需要实现diskio.c的底层操作,这里我用了两个文件,一个spi.c用于实现底层SPI的初始化和读写操作,一个sdcard.c用于实现对SD卡的操作封装。整体的工程框架如下:
这里将下diskio.c的一些修改部分:
- /* Definitions of physical drive number for each drive */
- #define DEV_SD 0 /* Example: Map SD/SD card to physical drive 1 */
- #define DEV_RAM 1 /* Example: Map Ramdisk to physical drive 0 */
- #define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
文件默认设置了三种存储系统,SD,RAM以及USB,我们使用的是SD,为了方便操作,我们将SD改为物理驱动0;
接下来就是实现后面的几个函数了,按照官方对函数的说明,我们调用自己的程序,并将自己的值与FATfs的值进行转化:
- DSTATUS disk_status (
- BYTE pdrv /* Physical drive nmuber to identify the drive */
- )
- {
- DSTATUS stat;
- int result;
- switch (pdrv) {
- case DEV_RAM :
- //result = RAM_disk_status();
- // translate the reslut code here
- stat = STA_NODISK;
- return stat;
- case DEV_SD :
- result = SD_disk_status();
- // translate the reslut code here
- if (result == 0)
- {
- stat = 0;
- }
- else
- {
- stat = STA_NODISK;
- }
- return stat;
- case DEV_USB :
- //result = USB_disk_status();
- // translate the reslut code here
- stat = STA_NODISK;
- return stat;
- }
- return STA_NOINIT;
- }
- /*-----------------------------------------------------------------------*/
- /* Inidialize a Drive */
- /*-----------------------------------------------------------------------*/
- DSTATUS disk_initialize (
- BYTE pdrv /* Physical drive nmuber to identify the drive */
- )
- {
- DSTATUS stat;
- int result;
- switch (pdrv) {
- case DEV_RAM :
- //result = RAM_disk_initialize();
- // translate the reslut code here
- stat = STA_NODISK;
- return stat;
- case DEV_SD :
- result = SD_disk_initialize();
- // translate the reslut code here
- if (result == 0)
- {
- stat = 0;
- }
- else
- {
- stat = STA_NODISK;
- }
- return stat;
- case DEV_USB :
- //result = USB_disk_initialize();
- // translate the reslut code here
- stat = STA_NODISK;
- return stat;
- }
- return STA_NOINIT;
- }
- /*-----------------------------------------------------------------------*/
- /* Read Sector(s) */
- /*-----------------------------------------------------------------------*/
- DRESULT disk_read (
- BYTE pdrv, /* Physical drive nmuber to identify the drive */
- BYTE *buff, /* Data buffer to store read data */
- DWORD sector, /* Start sector in LBA */
- UINT count /* Number of sectors to read */
- )
- {
- DRESULT res;
- int result;
- switch (pdrv) {
- case DEV_RAM :
- // translate the arguments here
- //result = RAM_disk_read(buff, sector, count);
- // translate the reslut code here
- res = RES_ERROR;
- return res;
- case DEV_SD :
- // translate the arguments here
- result = SD_disk_read(buff, sector, count);
- // translate the reslut code here
- res = result==0?RES_OK:RES_ERROR;
- return res;
- case DEV_USB :
- // translate the arguments here
- //result = USB_disk_read(buff, sector, count);
- // translate the reslut code here
- res = RES_ERROR;
- return res;
- }
- return RES_PARERR;
- }
- /*-----------------------------------------------------------------------*/
- /* Write Sector(s) */
- /*-----------------------------------------------------------------------*/
- #if FF_FS_READONLY == 0
- DRESULT disk_write (
- BYTE pdrv, /* Physical drive nmuber to identify the drive */
- const BYTE *buff, /* Data to be written */
- DWORD sector, /* Start sector in LBA */
- UINT count /* Number of sectors to write */
- )
- {
- DRESULT res;
- int result;
- switch (pdrv) {
- case DEV_RAM :
- // translate the arguments here
- //result = RAM_disk_write(buff, sector, count);
- // translate the reslut code here
- res = RES_ERROR;
- return res;
- case DEV_SD :
- // translate the arguments here
- result = SD_disk_write(buff, sector, count);
- // translate the reslut code here
- if (result == 0)
- {
- res = RES_OK;
- }
- else
- {
- res = RES_ERROR;
- }
- return res;
- case DEV_USB :
- // translate the arguments here
- //result = USB_disk_write(buff, sector, count);
- // translate the reslut code here
- res = RES_ERROR;
- return res;
- }
- return RES_PARERR;
- }
- #endif
- /*-----------------------------------------------------------------------*/
- /* Miscellaneous Functions */
- /*-----------------------------------------------------------------------*/
- DRESULT disk_ioctl (
- BYTE pdrv, /* Physical drive nmuber (0..) */
- BYTE cmd, /* Control code */
- void *buff /* Buffer to send/receive control data */
- )
- {
- DRESULT res;
- switch (pdrv) {
- case DEV_RAM :
- // Process of the command for the RAM drive
- return res;
- case DEV_SD :
- // Process of the command for the SD/SD card
- switch(cmd)
- {
- case CTRL_SYNC:
- res = RES_OK;
- break;
- case GET_SECTOR_SIZE:
- *(DWORD*)buff = g_sdCardInfo.sectorSize;
- res = RES_OK;
- break;
- case GET_BLOCK_SIZE:
- *(WORD*)buff = g_sdCardInfo.blockSize;
- res = RES_OK;
- break;
- case GET_SECTOR_COUNT:
- *(DWORD*)buff = g_sdCardInfo.sectorCount;
- res = RES_OK;
- break;
- default:
- res = RES_PARERR;
- break;
- }
- return res;
- case DEV_USB :
- // Process of the command the USB drive
- return res;
- }
- return RES_PARERR;
- }
实现完成后,我们就可以使用FATfs中的函数了,官网上对每一个API接口都有详细注释,部分函数还提供了使用示例,我们可以从官网的示例上找寻我们需要的代码:
- while(SD_disk_initialize()!=0)//can not find SD card
- {
- mdelay(1000);
- printf("Please Check! \r\n");
- }
- res = f_mount(&fs, "", 1);
- if (FR_OK != res)
- {
- printf("\r\nfirst mount disk error : %02x, format disk\r\n", res);
- res = f_mkfs("", FM_FAT32, 0, work, sizeof(work));
- if (FR_OK != res)
- {
- printf("\r\nformat disk error : %02x\r\n", res);
- return -1;
- }
- res = f_mount(&fs, "", 1);
- if (FR_OK != res)
- {
- printf("\r\nmount disk error : %02x\r\n", res);
- return -1;
- }
- }
- printf("\r\nmount disk success\r\n");
- strcpy(buff, "/");
- res = scan_files(buff);
这里我自己先调用了SD_disk_initialize函数确保能找到SD卡(实测有时候总会检测不到,不知道是不是因为SD卡和卡套之间接触问题还是焊接问题,需要插拔一下SD卡才行)。
在检测到SD卡后调用f_mount函数挂载SD卡,如果失败了,表示SD卡没有格式化,则将SD卡先格式化,再重新挂载。这里实现了一个scan_files函数,可以遍历SD卡中的所有文件。这里就不在赘述。
最后附上实现代码:
FATFS_sample.rar
(1.96 MB, 下载次数: 108)
|