STM32F103_SD卡FatFs文件系统移植

版权声明:转载注明出处 https://blog.csdn.net/weixin_42108004/article/details/82221828

一、下载解压官方源码压缩包

1 添加下列文件至项目列表并包含头文件。

二、配置函数接口

主要有以下几个文件 : diskio.c       ffconf.h

1  官方源码已经有写好的代码框架,只需要添加ATA(指SD卡)部分即可

(1) 获取设备状态部分,由于SD卡起始状态特别多,此处默认检测到SD卡设备。

    case ATA :
        //默认设备检测成功
        status &= ~STA_NOINIT;
    
        break;

(2) 设备初始化部分,调用sdio.c中的初始化函数即可。

    case ATA :
            if(SD_Init()==SD_OK)
            {
                status &= ~STA_NOINIT;
            }
            else 
            {
                status = STA_NOINIT;
            }
        
            break;

(3) 读扇区部分,由于SD卡读写时采用DMA,必须4字节对齐,当读缓冲区地址不是4字对齐时,必须特殊处理,先用disk_read()将数据读取至双字对齐的自定义数组中,然后利用memcpy()将数组的值复制至读数据缓冲区。当读缓冲区地址是4字对齐时,直接调用SD_ReadMultiBlocks() 读取即可。

    case ATA :
          if((DWORD)buff&3)
            {
                DRESULT res = RES_OK;
                DWORD scratch[SD_BLOCKSIZE / 4];

                while (count--) 
                {
                    res = disk_read(ATA,(BYTE *)scratch, sector++, 1);

                    if (res != RES_OK) 
                    {
                        break;
                    }
                    memcpy(buff, scratch, SD_BLOCKSIZE);
                    buff += SD_BLOCKSIZE;
            }
            status = res;
            }
            else
            {
                SD_state=SD_ReadMultiBlocks(buff,(uint64_t)sector*SD_BLOCKSIZE,SD_BLOCKSIZE,count);
                if(SD_state==SD_OK)
                {
                    /* Check if the Transfer is finished */
                    SD_state=SD_WaitReadOperation();
                    while(SD_GetStatus() != SD_TRANSFER_OK);
                }
                if(SD_state!=SD_OK)
                    status = RES_PARERR;
                else
                    status = RES_OK;    
            }

            break; 

(4)写扇区部分,原理同读。

    case ATA :
                if((DWORD)buff&3)
                {
                    DRESULT res = RES_OK;
                    DWORD scratch[SD_BLOCKSIZE / 4];

                    while (count--) 
                    {
                        memcpy( scratch,buff,SD_BLOCKSIZE);
                        res = disk_write(ATA,(BYTE *)scratch, sector++, 1);
                        if (res != RES_OK) 
                        {
                            break;
                        }                    
                        buff += SD_BLOCKSIZE;
                    }
                    status = res;
                    }        
                else
                {
                    SD_state=SD_WriteMultiBlocks((uint8_t *)buff,(uint64_t)sector*SD_BLOCKSIZE,SD_BLOCKSIZE,count);
                    if(SD_state==SD_OK)
                    {
                        /* Check if the Transfer is finished */
                        SD_state=SD_WaitWriteOperation();

                        /* Wait until end of DMA transfer */
                        while(SD_GetStatus() != SD_TRANSFER_OK);            
                    }
                    if(SD_state!=SD_OK)
                        status = RES_PARERR;
                    else
                        status = RES_OK;    
                }
                
                break;
(5)杂项参数配置。

    case ATA :
            switch (cmd) 
            {
                // Get R/W sector size (WORD) 
                case GET_SECTOR_SIZE :    
                    *(WORD * )buff = SD_BLOCKSIZE;
                break;
                // Get erase block size in unit of sector (DWORD)
                case GET_BLOCK_SIZE :      
                    *(DWORD * )buff = 1;
                break;

                case GET_SECTOR_COUNT:
                    *(DWORD * )buff = SDCardInfo.CardCapacity/SDCardInfo.CardBlockSize;
                    break;
                case CTRL_SYNC :
                break;
            }
            status = RES_OK;
            break;
至此diskio.c移植完成

三、ffconfig.h

需要修改的参数如下:

  //准许使用文件字符串函数: f_gets(), f_putc(), f_puts() and/  f_printf()

#define    _USE_STRFUNC    1    

//支持格式化函数f_mkfs()

#define    _USE_MKFS        1

//支持使用长文件名

#define    _USE_LFN    2
#define    _MAX_LFN    255

//使用UTF-8编码
#define _STRF_ENCODE    3

//设备数目
#define _VOLUMES    1

//支持最小最大扇区字节数

#define    _MIN_SS        512
#define    _MAX_SS        4096

//文件时间配置

#define _FS_NORTC    0
#define _NORTC_MON    1
#define _NORTC_MDAY    1
#define _NORTC_YEAR    2015

四、支持长文件名时需添加国标码字库文件

五、读写测试,函数参考官方提供的函数,如下:

猜你喜欢

转载自blog.csdn.net/weixin_42108004/article/details/82221828