TA的每日心情 | 开心 2019-6-20 14:08 |
---|
签到天数: 43 天 连续签到: 1 天 [LV.5]常住居民I
|
这周尝试通过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时钟
- /* 设置系统PLL PFD2 系数为18 */
- CLOCK_InitSysPfd(kCLOCK_Pfd0, 0x12U);
- /* 配置USDHC时钟源和分频系数 */
- CLOCK_SetDiv(kCLOCK_Usdhc1Div, 0U);
- CLOCK_SetMux(kCLOCK_Usdhc1Mux, 1U);
复制代码 (2)设置完sd host的地址和频率后,调用fsl_sd.c文件中的SD_HostInit(card)函数进行SD主机初始化工作和SD_CardInit(card)函数进行初始化sd卡工作。
- /*! @brief USDHC host descriptor */
- typedef struct _usdhc_host
- {
- USDHC_Type *base; /*!< USDHC peripheral base address */
- uint32_t sourceClock_Hz; /*!< USDHC source clock frequency united in Hz */
- usdhc_config_t config; /*!< USDHC configuration */
- usdhc_capability_t capability; /*!< USDHC capability information */
- usdhc_transfer_function_t transfer; /*!< USDHC transfer function */
- } usdhc_host_t;
复制代码 (3)初始化成功后,便可进行sdhc卡片工作信息的读取打印工作,如下图红色框显示
分别打印SD卡工作电压、时序模式和频率等信息。其对应的数据结构如下显示。- typedef struct _sd_card
- {
- SDMMCHOST_CONFIG host; /*!< Host information */
- sdcard_usr_param_t usrParam; /*!< user parameter */
- bool isHostReady; /*!< use this flag to indicate if need host re-init or not*/
- bool noInteralAlign; /*!< use this flag to disable sdmmc align. If disable, sdmmc will not make sure the
- data buffer address is word align, otherwise all the transfer are align to low level driver */
- uint32_t busClock_Hz; /*!< SD bus clock frequency united in Hz */
- uint32_t relativeAddress; /*!< Relative address of the card */
- uint32_t version; /*!< Card version */
- uint32_t flags; /*!< Flags in _sd_card_flag */
- uint32_t rawCid[4U]; /*!< Raw CID content */
- uint32_t rawCsd[4U]; /*!< Raw CSD content */
- uint32_t rawScr[2U]; /*!< Raw CSD content */
- uint32_t ocr; /*!< Raw OCR content */
- sd_cid_t cid; /*!< CID */
- sd_csd_t csd; /*!< CSD */
- sd_scr_t scr; /*!< SCR */
- uint32_t blockCount; /*!< Card total block number */
- uint32_t blockSize; /*!< Card block size */
- sd_timing_mode_t currentTiming; /*!< current timing mode */
- sd_driver_strength_t driverStrength; /*!< driver strength */
- sd_max_current_t maxCurrent; /*!< card current limit */
- sdmmc_operation_voltage_t operationVoltage; /*!< card operation voltage */
- } sd_card_t;
复制代码 (4)最后,进行sdhc卡的读写测试。这里也为将来的一帧图像信息的写入做好了准备,下一个实验就是基于此来进行尝试。
为了完成sd卡读/写操作,需要开辟读/写缓冲区。接下来,便可以调用fsl_sd.h中声明的库函数进行操作了。
- bool SD_CheckReadOnly(sd_card_t *card);
- status_t SD_ReadBlocks(sd_card_t *card, uint8_t *buffer, uint32_t startBlock, uint32_t blockCount);
- status_t SD_WriteBlocks(sd_card_t *card, const uint8_t *buffer, uint32_t startBlock, uint32_t blockCount);
- status_t SD_EraseBlocks(sd_card_t *card, uint32_t startBlock, uint32_t blockCount);
- bool SD_IsCardPresent(sd_card_t *card);
- status_t SD_WaitCardDetectStatus(SDMMCHOST_TYPE *hostBase, const sdmmchost_detect_card_t *cd, bool waitCardStatus);
- void SD_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
- void SD_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr);
- void SD_HostReset(SDMMCHOST_CONFIG *host);
- void SD_HostDeinit(sd_card_t *card);
- status_t SD_HostInit(sd_card_t *card);
- void SD_CardDeinit(sd_card_t *card);
- status_t SD_CardInit(sd_card_t *card);
- void SD_Deinit(sd_card_t *card);
- status_t SD_Init(sd_card_t *card);
复制代码 由上面代码可知,主要用到的就是SD_ReadBlocks、SD_WriteBlocks和SD_EraseBlocks这三个函数。其中指定第三个参数uint32_t blockCount的值1或者大于1,便可操作1个数据块或者多个数据块。实验效果如下图紫色框所示。
|
|