STM32入门学习笔记之SD卡基础读写实验4

发布时间:2023-09-27  

(2)创建sdio_sdcard.c文件,并输入以下代码。


#include "sdio_sdcard.h"

#include "string.h"



SD_CardInfo SDCardInfo ;                                        //SD卡信息

u8 CardType=SDIO_STD_CAPACITY_SD_CARD_V1_1 ;                              //SD卡类型

/***************************************************

Name    :SDIO_Clock_Set

Function  :SDIO发送命令函数

Paramater  :

      cmdindex:命令索引,低六位有效

      waitrsp:期待的相应

        00/10:无响应

        01:短响应

        11:长响应

      arg:参数

Return    :错误代码

***************************************************/

void SDIO_Send_Cmd( u8 cmdindex, u8 waitrsp, u32 arg )

{      

  u32 tmpreg ;

  SDIO->ARG = arg ;

  tmpreg = SDIO->CMD ;

  tmpreg &= 0xFFFFF800 ;                                        //清除index和waitrsp

  tmpreg |= cmdindex&0X3F ;                                      //设置新的index

  tmpreg |= waitrsp<<6 ;                                        //设置新的wait rsp

  tmpreg |= 0<<8 ;                                          //无等待

  tmpreg |= 1<<10 ;                                          //命令通道状态机使能

  SDIO->CMD = tmpreg ;

}

/***************************************************

Name    :SDIO_Send_Data_Cfg

Function  :SDIO发送数据配置函数

Paramater  :

      datatimeout:超时时间设置

      datalen:传输数据长度,低25位有效,必须为块大小的整数倍

      blksize:块大小.实际大小为:2^blksize字节

      dir:数据传输方向

        0:控制器到卡

        1:卡到控制器

Return    :错误代码

***************************************************/

void SDIO_Send_Data_Cfg( u32 datatimeout, u32 datalen, u8 blksize, u8 dir )

{

  u32 tmpreg;

  SDIO->DTIMER = datatimeout ;

  SDIO->DLEN = datalen&0x1FFFFFF ;                                  //低25位有效

  tmpreg = SDIO->DCTRL ; 

  tmpreg &= 0xFFFFFF08 ;                                        //清除之前的设置

  tmpreg |= blksize<<4 ;                                        //设置块大小

  tmpreg |= 0<<2 ;                                          //块数据传输

  tmpreg |= ( dir&0x01 )<<1 ;                                      //方向控制

  tmpreg |= 1<<0 ;                                          //数据传输使能,DPSM状态机

  SDIO->DCTRL = tmpreg ;

}

/***************************************************

Name    :SDIO_Clock_Set

Function  :SDIO时钟初始化设置

Paramater  :

      clkdiv:时钟分频系数

Return    :错误代码

***************************************************/

void SDIO_Clock_Set( u8 clkdiv )

{

  u32 tmpreg = SDIO->CLKCR ;

  tmpreg &= 0xFFFFFF00 ;

  tmpreg |= clkdiv;

  SDIO->CLKCR = tmpreg ;

}

/***************************************************

Name    :CmdError

Function  :检查CMD0的执行状态

Paramater  :None

Return    :错误代码

***************************************************/

SD_Error CmdError()

{

  SD_Error errorstatus = SD_OK ;

  u32 timeout=SDIO_CMD0TIMEOUT ;

  while( timeout-- )

  {

    //命令已发送(无需响应)

    if( SDIO->STA&( 1<<7 ) )

      break ;

  }

  if( timeout==0 )

    return SD_CMD_RSP_TIMEOUT ;

  SDIO->ICR = 0x5FF ;                                          //清除标记

  return errorstatus ;

}

/***************************************************

Name    :CmdResp7Error

Function  :检查R7响应的错误状态

Paramater  :None

Return    :错误代码

***************************************************/

SD_Error CmdResp7Error()

{

  u32 status ;

  u32 timeout = 0x00010000 ;

   while( timeout-- )

  {

    status = SDIO->STA ;

    if( ( status&0x45 )!=0 )                                    //等待接收到应答

      break ;

  }

  //响应超时

   if( ( timeout==0 )||( ( status&0x04 )==0x04 ) )

  {

    //当前卡不是2.0兼容卡,或者不支持设定的电压范围

    SDIO->ICR |= 1<<2 ;                                        //清除命令响应超时标志

    return SD_CMD_RSP_TIMEOUT ;

  }

  //成功接收到响应

  if( ( status&0x40 )==0x40 )

    SDIO->ICR |= 1<<6 ;                                        //清除响应标志

  return SD_OK ;

}

/***************************************************

Name    :CmdResp1Error

Function  :检查R1响应的错误状态

Paramater  :

      cmd:当前命令

Return    :错误代码

***************************************************/

SD_Error CmdResp1Error( u8 cmd )

{    

     u32 status ;

  while( 1 )

  {

    status = SDIO->STA ;

    if( ( status&0x45 )!=0 )                                    //等待接收到应答

      break ;

  }

  //响应超时

  if( ( status&0x04 )==0x04 )

  {

     SDIO->ICR |= 1<<2 ;                                        //清除命令响应超时标志

    return SD_CMD_RSP_TIMEOUT ;

  }

  //CRC错误

   if( ( status&0x01 )==0x01 )

  {

     SDIO->ICR |= 1<<0;                                        //清除标志

    return SD_CMD_CRC_FAIL;

  }

  if( SDIO->RESPCMD!=cmd )

    return SD_ILLEGAL_CMD ;                                      //命令不匹配

    SDIO->ICR = 0x5FF ;                                          //清除标记

  return ( SD_Error )( SDIO->RESP1&0xFDFFE008 ) ;                            //返回卡响应

}

/***************************************************

Name    :CmdResp3Error

Function  :检查R3响应的错误状态

Paramater  :None

Return    :错误代码

***************************************************/

SD_Error CmdResp3Error()

{

  u32 status ;             

   while( 1 )

  {

    status = SDIO->STA ;

    if( ( status&0x45 )!=0 )                                     //等待接收到应答

      break ;

  }

  //响应超时

   if( ( status&0x04 )==0x04 )

  {

    SDIO->ICR |= 1<<2 ;                                        //清除命令响应超时标志

    return SD_CMD_RSP_TIMEOUT ;

  }

     SDIO->ICR = 0x5FF ;                                          //清除标记

   return SD_OK ;

}

/***************************************************

Name    :CmdResp2Error

Function  :检查R2响应的错误状态

Paramater  :None

Return    :错误代码

***************************************************/

SD_Error CmdResp2Error()

{

  u32 status ;

  u32 timeout = 0x00010000 ;

   while( timeout-- )

  {

    status = SDIO->STA ;

    if( ( status&0x45 )!=0 )                                    //接收到R2响应

      break ;

  }

  //响应超时

    if( ( timeout==0 )||( ( status&0x04 )==0x04 ) )

  {

    SDIO->ICR |= 1<<2 ;                                        //清除命令响应超时标志

    return SD_CMD_RSP_TIMEOUT ;

  }

  //CRC错误

  if( ( status&0x01 )==0x01 )

  {

    SDIO->ICR |= 1<<0 ;                                        //清除响应标志

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>