当前位置:   article > 正文

使用MCU的 GPIO口 模拟SDIO时序读写TF/SD卡的可能性。

使用MCU的 GPIO口 模拟SDIO时序读写TF/SD卡的可能性。

SD2.0协议详解:命令格式、初始化/读取/写入 - WangXuan的文章 - 知乎
https://zhuanlan.zhihu.com/p/610495260

参考上述与其它理解,若使用GPIO口模拟,重点与难点:

1.  时钟线问题:

    在SD准备期间,需不间断一直发送频率为100kHz- 400kHz的时钟 以让SD卡初始化,在初始化完成后,时钟频率为0-25MHZ,此要求意味着:

    在空闲时:需由PWM或定时器产生需要的持续时钟(初始化完成后应该可以停止了),

     在工作时:暂停此时钟并使用GPIO模拟,工作完成后继续此时钟(初始化完成后应该可以关闭,但未验证)。

2. 校验码问题:

    CMD线和每根DAT线,自身独立产生校验码,CMD线为CRC7, DAT线为CRC16,此要求

      (1. 在写 CMD上时问题不大,写入前先计算好后一次性写入。  

      (2. 在读SD卡时返回时,若简化设计,可选择忽略。

      (3.在向SD写入时,将产生一定的计算量,以4线为例每线为1024位,共512*8=4096位。

3. 其它:

    (1. 模拟时,CMD的起始+方向+指令共6字节,可看作为一个字节,校验7位+停止位看作最后一字节。

      2. 描述中的由host→card共6位指令的“CMDn”,中的n对应0-63,为标准指令,后跟对应32位数据。

      3. 描述中的响应 (response) 即从 card 到 host,用"R1-7“表示,CMDn与之有对应关系见相关手册。格式同CMDn,但R2例外有共136bit。

物理IO层结构设计:

  考虑到一个应用绝大多数情况只有一个SD卡即一条SDIO总线,故直接单例化设计以提高效率

1. 内部主要函数功能设计:(位于 SDIO_Soft.c中, 仅支持4线DAT模式)

       _IoInit():    初始化Clk线为输出,其它线为输入上拉。

            _SetClk(HZ): 用于配置CLK为指定频率,需用PWM或定时器翻转IO实现

            _OnClk(): 开始输出固定频率到Clk线上

            _OffClk(): 关闭Clk

     _NoneClk(U8): 发送指定个数据时钟,其它位不操作。

    _Sendmd(u8 Cmd): 发送8位指令

    _RcvCmd(u8 BitCount): 接收指定位应答入接收指令缓冲,返回收到位数长度

    _SendData(u8只读指针,u16数据个数): 发送指定数据到4线dat上。

    _RcvData(8只读指针,u16数据个数): 从4线dat上接收指定数据个数,内部可选接收期间同时收应答指令(放入接收指令缓冲中)。

2. 对外统一函数接口  SDIO.h

    设计为SDIO操作的通用接口,对其它MCU的SDIO硬件可封装为此接口以方便上层操作。

     SDIO_Init():初始化IO,开启时钟等。

     SDIO_Cmd(u8指令, u32数据,u8前置),发送指令,此函数内部计算好校验码后依次发出,在U8指令信息的b7置位时,接收响应,接收的响应保存入SDIO单例化结构中。返回0正确,其它为错误码

     SDIO_RdBlock(u8可写数据指针): 上层在带读数据的指令发出后,立即调用此函数读入一块数据,长度固定为512,注意多收尾部的校验码。返回0正确,其它为错误码

     SDIO_WrBlock(u8只读数据指针): 上层在带写数据的指令发出后,立即调用此函数写出一块数据,长度固定为512,在内部提交计算好CRC16校验码,在尾部发出。返回0正确,其它为错误码

     其它函数: 为可选, 仅硬件实现的SDIO支持,如:DMA, 读写多块等。

      

    

    

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/590527
推荐阅读
相关标签
  

闽ICP备14008679号