[经验] stm32f769 寄存器配置SD卡驱动--SD_InitializeCards函数

[复制链接]

版主

发表于 2018-3-23 11:37:06   421 查看 0 回复 显示全部楼层 倒序浏览
分享
本帖最后由 lee_st 于 2018-3-24 10:35 编辑

下面是实现SD_InitializeCards的初始化函数
SD_Error SD_InitializeCards(void)
{
         SD_Error errorstatus=SD_OK;
        u16 rca = 0x01;
         if((SDMMC2->POWER&0X03)==0)return SD_REQUEST_NOT_APPLICABLE;//检查电源状态,确保为上电状态
         if(SECURE_DIGITAL_IO_CARD!=CardType)                                //非SECURE_DIGITAL_IO_CARD
        {
                SDMMC_Send_Cmd(SD_CMD_ALL_SEND_CID,3,0);                        //发送CMD2,取得CID,长响应         
                errorstatus=CmdResp2Error();                                         //等待R2响应   
                if(errorstatus!=SD_OK)return errorstatus;           //响应错误                    
                 CID_Tab[0]=SDMMC2->RESP1;
                CID_Tab[1]=SDMMC2->RESP2;
                CID_Tab[2]=SDMMC2->RESP3;
                CID_Tab[3]=SDMMC2->RESP4;
        }
        if((STD_CAPACITY_SD_CARD_V1_1==CardType)||(STD_CAPACITY_SD_CARD_V2_0==CardType)||(SECURE_DIGITAL_IO_COMBO_CARD==CardType)||(HIGH_CAPACITY_SD_CARD==CardType))//判断卡类型
        {
                SDMMC_Send_Cmd(SD_CMD_SET_REL_ADDR,1,0);                        //发送CMD3,短响应
                errorstatus=CmdResp6Error(SD_CMD_SET_REL_ADDR,&rca);//等待R6响应
                if(errorstatus!=SD_OK)return errorstatus;           //响应错误                    
        }   
    if (MULTIMEDIA_CARD==CardType)
    {
                 SDMMC_Send_Cmd(SD_CMD_SET_REL_ADDR,1,(u32)(rca<<16));//发送CMD3,短响应            
                errorstatus=CmdResp2Error();                                         //等待R2响应   
                if(errorstatus!=SD_OK)return errorstatus;           //响应错误         
    }
        if (SECURE_DIGITAL_IO_CARD!=CardType)                        //非SECURE_DIGITAL_IO_CARD
        {
                RCA = rca;
                SDMMC_Send_Cmd(SD_CMD_SEND_CSD,3,(u32)(rca<<16));//发送CMD9+卡RCA,取得CSD,长响应            
                errorstatus=CmdResp2Error();                                         //等待R2响应   
                if(errorstatus!=SD_OK)return errorstatus;           //响应错误                    
                  CSD_Tab[0]=SDMMC2->RESP1;
                CSD_Tab[1]=SDMMC2->RESP2;
                CSD_Tab[2]=SDMMC2->RESP3;                                                
                CSD_Tab[3]=SDMMC2->RESP4;                                            
        }
        return SD_OK;//卡初始化成功
}

里面的调用的函数CmdResp2Error()
SD_Error CmdResp2Error(void)
{
        SD_Error errorstatus=SD_OK;
        u32 status;
        u32 timeout=SDMMC_CMD0TIMEOUT;
         while(timeout--)
        {
                status=SDMMC2->STA;
                if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)        
        }
          if((timeout==0)||(status&(1<<2)))        //响应超时
        {                                                                                                                                                                    
                errorstatus=SD_CMD_RSP_TIMEOUT;
                SDMMC2->ICR|=1<<2;                                //清除命令响应超时标志
                return errorstatus;
        }         
        if(status&1<<0)                                                //CRC错误
        {                                                                  
                errorstatus=SD_CMD_CRC_FAIL;
                SDMMC2->ICR|=1<<0;                                //清除响应标志
         }
        SDMMC2->ICR=0X5FF;                                         //清除标记
         return errorstatus;                                                                                    
}

SD_Error CmdResp6Error(u8 cmd,u16*prca)
{
        SD_Error errorstatus=SD_OK;
        u32 status;                                            
        u32 rspr1;
         while(1)
        {
                status=SDMMC2->STA;
                if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)        
        }
        if(status&(1<<2))                                        //响应超时
        {                                                                                                                                                                    
                 SDMMC2->ICR|=1<<2;                                //清除命令响应超时标志
                return SD_CMD_RSP_TIMEOUT;
        }                  
        if(status&1<<0)                                                //CRC错误
        {                                                                  
                SDMMC2->ICR|=1<<0;                                //清除响应标志
                 return SD_CMD_CRC_FAIL;
        }
        if(SDMMC2->RESPCMD!=cmd)                        //判断是否响应cmd命令
        {
                 return SD_ILLEGAL_CMD;                 
        }            
        SDMMC2->ICR=0X5FF;                                         //清除所有标记
        rspr1=SDMMC2->RESP1;                                //得到响应         
        if(SD_ALLZERO==(rspr1&(SD_R6_GENERAL_UNKNOWN_ERROR|SD_R6_ILLEGAL_CMD|SD_R6_COM_CRC_FAILED)))
        {
                *prca=(u16)(rspr1>>16);                        //右移16位得到,rca
                return errorstatus;
        }
           if(rspr1&SD_R6_GENERAL_UNKNOWN_ERROR)return SD_GENERAL_UNKNOWN_ERROR;
           if(rspr1&SD_R6_ILLEGAL_CMD)return SD_ILLEGAL_CMD;
           if(rspr1&SD_R6_COM_CRC_FAILED)return SD_COM_CRC_FAILED;
        return errorstatus;
}














评分

参与人数 2积分 +10 收起 理由
ElecFans王岑 + 5
star_66666 + 5 资源分享达人,加分鼓励!

查看全部评分

标签:寄存器 配置 驱动
高级模式
您需要登录后才可以回帖 登录 | 注册

关闭

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

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

推荐专区

技术干货集中营

专家问答

用户帮助┃咨询与建议┃版主议事

工程师杂谈

工程师创意

工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

ARM技术论坛

Android论坛

Linux论坛

单片机/MCU论坛

MSP430技术论坛

FPGA|CPLD|ASIC论坛

STM32/STM8技术论坛

NXP MCU 技术论坛

PIC单片机论坛

DSP论坛

瑞萨单片机论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

无线充电技术

-

硬件设计论坛

PCB设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PADS技术论坛

Protel|AD|DXP论坛

Allegro论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

Orcad论坛

-

综合技术与应用

电机控制

智能电网

光电及显示

参考设计中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

厂商专区

TI论坛

TI Deyisupport社区

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

招聘┃求职发布区

电子展览展会专区