查看: 2379|回复: 2

[原创] 【LPC55S69】TF卡(SDIO+FATFS)

[复制链接]
  • TA的每日心情
    无聊
    2021-12-29 19:06
  • 签到天数: 47 天

    [LV.5]常住居民I

    49

    主题

    188

    帖子

    21

    金牌会员

    Rank: 6Rank: 6

    积分
    1371
    最后登录
    2024-3-21
    发表于 2020-3-12 21:27:38 | 显示全部楼层 |阅读模式
    本帖最后由 day_day 于 2020-3-12 21:45 编辑

    (一)SDK
    SDK加入:
    Drivers-sdif
    Middleware-file system-fatfs+sd+ram
    Middleware-memories-common+sd


    (二)引脚配置
    11.png



    (三)时钟
    12.png

    时钟绝对不可以使用pll1_clk,也不能是从这个时钟来的其他分支,比如main_clk如果是从pll1_clk来的同样不能用。这个时钟坑过我一次,无论如何都无法驱动!


    (四)移植sdmmc

    移植工作可以直接从例程中拷过来,例程中的sdmmc-port文件夹直接整个靠到自己生成的工程下。



    (五)设置fatfs为sd卡器件
    SDK导入完毕后,source里面有一个ffconf.h文件

    #define RAM_DISK_ENABLE
    改为
    #define SD_DISK_ENABLE



    (六)头文件
    1. #include "fsl_sd.h"
    2. #include "fsl_sd_disk.h"

    3. #include "ffconf.h"
    4. #include "ff.h"
    5. #include "diskio.h"
    复制代码


    (七)全局变量
    1. static status_t sdcardWaitCardInsert(void);
    2. static const sdmmchost_detect_card_t s_sdCardDetect = {
    3.     .cdType = BOARD_SD_DETECT_TYPE,
    4.     .cdTimeOut_ms = (~0U),
    5. };
    复制代码





    (八)检测SD卡并上电
    1. static status_t sdcardWaitCardInsert(void)
    2. {
    3.     /* Save host information. */
    4.     g_sd.host.base           = SD_HOST_BASEADDR;
    5.     g_sd.host.sourceClock_Hz = SD_HOST_CLK_FREQ;
    6.     /* card detect type */
    7.     g_sd.usrParam.cd = &s_sdCardDetect;
    8.     /* SD host init function */
    9.     if (SD_HostInit(&g_sd) != kStatus_Success)
    10.     {
    11.         PRINTF("\r\nSD host init fail\r\n");
    12.         return kStatus_Fail;
    13.     }
    14.     /* power off card */
    15.     SD_PowerOffCard(g_sd.host.base, g_sd.usrParam.pwr);
    16.     /* wait card insert */
    17.     if (SD_WaitCardDetectStatus(SD_HOST_BASEADDR, &s_sdCardDetect, true) == kStatus_Success)
    18.     {
    19.         PRINTF("\r\nCard inserted.\r\n");
    20.         /* power on the card */
    21.         SD_PowerOnCard(g_sd.host.base, g_sd.usrParam.pwr);
    22.     }
    23.     else
    24.     {
    25.         PRINTF("\r\nCard detect fail.\r\n");
    26.         return kStatus_Fail;
    27.     }

    28.     return kStatus_Success;
    29. }
    复制代码
    Main函数里面:

    1. //insert tf car
    2.     while (sdcardWaitCardInsert() != kStatus_Success){
    3.             PRINTF("\r\nPlease insert a card into board.\r\n");
    4.             SysTick_DelayTicks(1000);
    5. }
    复制代码




    (九)驱动代码
    1. //value
    2.     static FATFS g_fileSystem;
    3.     static FIL g_fileObject;

    4.     const TCHAR driverNumberBuffer[3U] = {SDDISK + '0', ':', '/'};
    5.     BYTE work[FF_MAX_SS];

    6.     //mount
    7.     if (f_mount(&g_fileSystem, driverNumberBuffer, 0U))
    8.     {
    9.             PRINTF("Mount volume failed.\r\n");
    10.             while(1);
    11.     }

    12.     //chdrive
    13.     if(f_chdrive((char const *)&driverNumberBuffer[0U]))
    14.     {
    15.             PRINTF("Change drive(f_chdrive) failed.\r\n");
    16.             while(1);
    17.     }

    18.     //make fs
    19.     if (f_mkfs(driverNumberBuffer, FM_ANY, 0U, work, sizeof work))
    20.     {
    21.             PRINTF("Make file system failed.\r\n");
    22.             while(1);
    23.     }

    24.     //mkdir
    25.     FRESULT error = f_mkdir(_T("/dir_1"));
    26.     if (error)
    27.     {
    28.             if (error == FR_EXIST)
    29.             {
    30.                     PRINTF("Directory exists.\r\n");
    31.             }
    32.             else
    33.             {
    34.                     PRINTF("Make directory failed.\r\n");
    35.                     return -1;
    36.             }
    37.     }
    38.     else
    39.             PRINTF("Make directory success.\r\n");
    复制代码


    可以看到tf卡里面多了个dir_1文件夹

    (十)注意

    1-不能在中断里面读写
    官方移植的FATFS读写接口有个BUGsdmmc-port中的fsl_sdmmc_event.c文件里面有个 SDMMCEVENT_Wait 函数,这个函数等待是采用计数的方式实现。但这个计数依靠systick中断服务函数周期地自增。如果默认没有配置systick拥有更高的抢断优先级的话,一旦在任意中断服务函数里面读写tf卡都会导致卡死。
    应尽量避免在中断服务函数里面读写fatfs;或者设置中断优先级;或者优化代码,采用轮询读取
    不过从软件架构的角度来说,在中断这种暂时性强的时期做大量的读写任务也并不明智。可以通过标志位来指示主循环处理tf卡和fatfs的读写任务。


    2-绝对不能用PLL1向SDIO提供时钟
    PLL1 到 MAIN_CLK 再到SDIO也不行,fatfs读写会莫名没有响应


    工程: LPC55S69_Project_tf.zip (1.22 MB, 下载次数: 211)
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    前天 14:17
  • 签到天数: 1337 天

    [LV.10]以坛为家III

    88

    主题

    4294

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9059
    最后登录
    2024-5-6
    发表于 2020-3-13 10:44:04 | 显示全部楼层
    这个真棒,我一直想实现SD的大量读写,到现在还在计划中……
    惭愧啊
    今天天气不错!签到!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 20:36
  • 签到天数: 1484 天

    [LV.10]以坛为家III

    203

    主题

    2万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    93044
    最后登录
    2024-5-7
    发表于 2020-3-15 00:37:25 | 显示全部楼层
    不错不错,支持一下 1.png 2.png 3.png 4.png 8.png 7.png 6.png 5.png 9.png 10.png
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-5-8 07:05 , Processed in 0.116120 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表