查看: 3969|回复: 0

[原创] 野火i.MX RT1052 MINI试用-6-SD卡读写实验

[复制链接]
  • TA的每日心情
    开心
    2019-6-20 14:08
  • 签到天数: 43 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2018-7-8 21:25:02 | 显示全部楼层 |阅读模式
    分享到:
          这周尝试通过RT1052对SD卡进行操作。原本想着将图像存到spi flash中,那样确实简单些,但是不符合常规认识。所以还是采用将图像存到SD卡中的方式。为了实现这个目的,我随便找了张micro卡试了一下,结果没有成功,debug原因在fsl_usdhc.c文件中的USDHC_WaitCommandDone函数第714行interruptStatus = USDHC_GetInterruptStatusFlags(base);,分析原因是卡的类型不对,这里需要的是SDHC。拔下卡一看,果然我插了一块512MB的1代micro sd卡,于是更换了一块4GB的2.0规范的SDHC(SD high capacity)卡,结果识别正确。
          工作流程:
       (1)初始化SDHC时钟
    1.      /* 设置系统PLL PFD2 系数为18 */
    2.     CLOCK_InitSysPfd(kCLOCK_Pfd0, 0x12U);
    3.     /* 配置USDHC时钟源和分频系数 */
    4.     CLOCK_SetDiv(kCLOCK_Usdhc1Div, 0U);
    5.     CLOCK_SetMux(kCLOCK_Usdhc1Mux, 1U);
    复制代码
        (2)设置完sd host的地址和频率后,调用fsl_sd.c文件中的SD_HostInit(card)函数进行SD主机初始化工作和SD_CardInit(card)函数进行初始化sd卡工作。
    1. /*! @brief USDHC host descriptor */
    2. typedef struct _usdhc_host
    3. {
    4.     USDHC_Type *base;                   /*!< USDHC peripheral base address */
    5.     uint32_t sourceClock_Hz;            /*!< USDHC source clock frequency united in Hz */
    6.     usdhc_config_t config;              /*!< USDHC configuration */
    7.     usdhc_capability_t capability;      /*!< USDHC capability information */
    8.     usdhc_transfer_function_t transfer; /*!< USDHC transfer function */
    9. } usdhc_host_t;
    复制代码
         (3)初始化成功后,便可进行sdhc卡片工作信息的读取打印工作,如下图红色框显示
    11.png 分别打印SD卡工作电压、时序模式和频率等信息。其对应的数据结构如下显示。
    1. typedef struct _sd_card
    2. {
    3.     SDMMCHOST_CONFIG host; /*!< Host information */

    4.     sdcard_usr_param_t usrParam;    /*!< user parameter */
    5.     bool isHostReady;               /*!< use this flag to indicate if need host re-init or not*/
    6.     bool noInteralAlign;            /*!< use this flag to disable sdmmc align. If disable, sdmmc will not make sure the
    7.                                     data buffer address is word align, otherwise all the transfer are align to low level driver */
    8.     uint32_t busClock_Hz;           /*!< SD bus clock frequency united in Hz */
    9.     uint32_t relativeAddress;       /*!< Relative address of the card */
    10.     uint32_t version;               /*!< Card version */
    11.     uint32_t flags;                 /*!< Flags in _sd_card_flag */
    12.     uint32_t rawCid[4U];            /*!< Raw CID content */
    13.     uint32_t rawCsd[4U];            /*!< Raw CSD content */
    14.     uint32_t rawScr[2U];            /*!< Raw CSD content */
    15.     uint32_t ocr;                   /*!< Raw OCR content */
    16.     sd_cid_t cid;                   /*!< CID */
    17.     sd_csd_t csd;                   /*!< CSD */
    18.     sd_scr_t scr;                   /*!< SCR */
    19.     uint32_t blockCount;            /*!< Card total block number */
    20.     uint32_t blockSize;             /*!< Card block size */
    21.     sd_timing_mode_t currentTiming; /*!< current timing mode */
    22.     sd_driver_strength_t driverStrength;        /*!< driver strength */
    23.     sd_max_current_t maxCurrent;                /*!< card current limit */
    24.     sdmmc_operation_voltage_t operationVoltage; /*!< card operation voltage */
    25. } sd_card_t;
    复制代码
        (4)最后,进行sdhc卡的读写测试。这里也为将来的一帧图像信息的写入做好了准备,下一个实验就是基于此来进行尝试。


           为了完成sd卡读/写操作,需要开辟读/写缓冲区。接下来,便可以调用fsl_sd.h中声明的库函数进行操作了。
    1. bool SD_CheckReadOnly(sd_card_t *card);
    2. status_t SD_ReadBlocks(sd_card_t *card, uint8_t *buffer, uint32_t startBlock, uint32_t blockCount);
    3. status_t SD_WriteBlocks(sd_card_t *card, const uint8_t *buffer, uint32_t startBlock, uint32_t blockCount);
    4. status_t SD_EraseBlocks(sd_card_t *card, uint32_t startBlock, uint32_t blockCount);
    5. bool SD_IsCardPresent(sd_card_t *card);
    6. status_t SD_WaitCardDetectStatus(SDMMCHOST_TYPE *hostBase, const sdmmchost_detect_card_t *cd, bool waitCardStatus);
    7. void SD_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
    8. void SD_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
    9. void SD_HostReset(SDMMCHOST_CONFIG *host);
    10. void SD_HostDeinit(sd_card_t *card);
    11. status_t SD_HostInit(sd_card_t *card);
    12. void SD_CardDeinit(sd_card_t *card);
    13. status_t SD_CardInit(sd_card_t *card);
    14. void SD_Deinit(sd_card_t *card);
    15. status_t SD_Init(sd_card_t *card);
    复制代码
           由上面代码可知,主要用到的就是SD_ReadBlocks、SD_WriteBlocksSD_EraseBlocks这三个函数。其中指定第三个参数uint32_t blockCount的值1或者大于1,便可操作1个数据块或者多个数据块。实验效果如下图紫色框所示。
    11.png
    回复

    使用道具 举报

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

    本版积分规则

    关闭

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



    手机版|小黑屋|与非网

    GMT+8, 2025-1-12 21:37 , Processed in 0.111232 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.