W806 开发板 SDIO 方式初始化 SD 卡时发送 CMD2 读取 CID 时 R2 响应失败

发布于 2022-11-01 16: 33: 50

W806 使用 SDIO 方式初始化 SD 卡时, 发送 CMD2 命令后获取响应 R2 失败, 希望大神指点.
1. PNG
2. PNG
发送 CMD2 获取 CID 的 R2 响应时失败, SD 卡 2. 0 手册 R2 响应 Bit[135-128]=0x3F, 程序读取该值一直为 0
程序如下: {{sdio. c (uploading. . . ) }}

3. jpg

define SDIO SDIO_HOST

define CMD_BUFF[x] CMD_BUF[x]

define SDIO_CLK PB6

define SDIO_CMD PB7

define SDIO_D0 PB8

define SDIO_D1 PB9

define SDIO_D2 PB10

define SDIO_D3 PB11//OPT2

define SDIO_GPIO GPIOB

uint8 SD_CardType=0;
// SD 卡类型定义

define SD_TYPE_ERR 0x00

define SD_TYPE_MMC 0x01

define SD_TYPE_V1 0x02

define SD_TYPE_V2 0x04

define SD_TYPE_V2HC 0x06

//SD 卡指令表

define CMD0 0 //卡复位

define CMD1 1

define CMD2 2

define CMD3 3

define CMD8 8 //命令 8 , SEND_IF_COND

define CMD9 9 //命令 9 , 读 CSD 数据

define CMD10 10 //命令 10, 读 CID 数据

define CMD12 12 //命令 12, 停止数据传输

define CMD16 16 //命令 16, 设置 SectorSize 应返回 0x00

define CMD17 17 //命令 17, 读 sector

define CMD18 18 //命令 18, 读 Multi sector

define CMD23 23 //命令 23, 设置多 sector 写入前预先擦除 N 个 block

define CMD24 24 //命令 24, 写 sector

define CMD25 25 //命令 25, 写 Multi sector

define CMD41 41 //命令 41, 应返回 0x00

define CMD55 55 //命令 55, 应返回 0x01

define CMD58 58 //命令 58, 读 OCR 信息

define CMD59 59 //命令 59, 使能/禁止 CRC, 应返回 0x00

define MMC_CMD1_ARG 0x80FF8000 //MMC 卡 CMD1 命令参数

//MMC_IO 配置

define MMC_IO_NoAction 0 //MMC_IO 无操作

define MMC_IO_JusCret8nck 0x24 //MMC_IO 生成 8 个空闲时钟

define MMC_IO_SendCmd6 0x04 //发送 6 字节命令

define MMC_IO_Response6 0x0C //接收 6 字节响应

define MMC_IO_Response17 0x1C //接收 17 字节响应

define MMC_IO_Cmd8nclk 0x84 //传输命令+8 个空闲时钟

define MMC_IO_CmdRecSp 0x44 //传输命令+接收响应

define MMC_IO_RradCidCsdRecp 0x54 //传输命令+接收 CSD, CID

define MMC_IO_CmdResp8nclk 0xC4 //

define MMC_IO_ReadDat8nck 0x03 //读 MMC_BYTECNT 字节

define MMC_IO_WriteDat8nck 0x01 //写 MMC_BYTECNT 字节

enum SdCardResponse {SDIOCmdError, SDIOCmdTrue}; //命令响应判断
enum SDflag { SDTrue, SDFall}; //函数返回值: 成功/失败

define SDIO_CLK_EN 18

define SDIO_CLK_RE 27

define Max_RepeatCount 100 //定义重复发送数据最大值

void Init_SDIO_IO ()
{

RCC- RST&=~BIT (SDIO_CLK_RE) ; 
RCC- RST|=BIT (SDIO_CLK_RE) ; 
while (!  (RCC- RST&BIT (SDIO_CLK_RE) ) ) ;     //复位 SDIO 模块

RCC- CLK_EN|=BIT (SDIO_CLK_EN) ; 
RCC- CLK_MASK|=BIT (1) ;                     //时钟使能

SDIO_GPIO- DATA_B_EN|=BIT (SDIO_CLK) |BIT (SDIO_CMD) |BIT (SDIO_D0) |BIT (SDIO_D1) |BIT (SDIO_D2) |BIT (SDIO_D3) ; 
SDIO_GPIO- PULLUP_EN&=~ (BIT (SDIO_CLK) |BIT (SDIO_CMD) |BIT (SDIO_D0) |BIT (SDIO_D1) |BIT (SDIO_D2) |BIT (SDIO_D3) ) ; 
SDIO_GPIO- DIR|=BIT (SDIO_CLK) |BIT (SDIO_CMD) |BIT (SDIO_D0) |BIT (SDIO_D1) |BIT (SDIO_D2) |BIT (SDIO_D3) ; 
SDIO_GPIO- DATA|=BIT (SDIO_CLK) |BIT (SDIO_CMD) |BIT (SDIO_D0) |BIT (SDIO_D1) |BIT (SDIO_D2) |BIT (SDIO_D3) ; 

SDIO_GPIO- AF_SEL|=BIT (SDIO_CLK) |BIT (SDIO_CMD) |BIT (SDIO_D0) |BIT (SDIO_D1) |BIT (SDIO_D2) |BIT (SDIO_D3) ; 
SDIO_GPIO- AF_S0|=BIT (SDIO_CLK) |BIT (SDIO_CMD) |BIT (SDIO_D0) |BIT (SDIO_D1) |BIT (SDIO_D2) |BIT (SDIO_D3) ; 
SDIO_GPIO- AF_S1&=~ (BIT (SDIO_CLK) |BIT (SDIO_CMD) |BIT (SDIO_D0) |BIT (SDIO_D1) |BIT (SDIO_D2) |BIT (SDIO_D3) ) ; 

}

void SDIO_LowSpeed ()
{

SDIO- MMC_CTL&=0x7C7;         
SDIO- MMC_CTL|=BIT (5) |BIT (3) ; 
SDIO- MMC_CARDSEL&=0xC0;     
SDIO- MMC_CARDSEL|=0x18;      
SDIO- MMC_CTL&=~BIT (6) ;         

}

void WaiteCmdTransOver ()
{

while (!  (SDIO- MMC_INT_SRC&BIT (0) ) ) ; //等待命令传输完成
SDIO- MMC_INT_SRC|=BIT (0) ;         //清零标志位

}

void SD_SendCmd (uint8 cmd, uint32 cmdarg, uint8 mmcio)
{

SDIO- CMD_BUFF[4]= (cmd|0x40) ; 
SDIO- CMD_BUFF[3]= ( (cmdarg  24) &0xFF) ; 
SDIO- CMD_BUFF[2]= ( (cmdarg  16) &0xFF) ; 
SDIO- CMD_BUFF[1]= ( (cmdarg  8) &0xFF) ; 
SDIO- CMD_BUFF[0]= (cmdarg&0xFF) ; 

SDIO- MMC_INT_SRC|=0x1FF; 
SDIO- MMC_IO=mmcio;         

if (cmd==CMD12) 
{
    //
}

}

void Init_SDIO_Reg ()
{

SDIO- MMC_CARDSEL|=BIT (7) |BIT (6) ; 
SDIO- MMC_CTL=BIT (1) |BIT (0) ; //1bit 模式
SDIO- MMC_PORT=0xFF; 
SDIO- MMC_CRCCTL=BIT (7) |BIT (6) ; 

}
uint8 SDIO_GetResponseR1 (uint8 cmd, uint32 指针符号 responR1)
{

while (!  (SDIO- MMC_INT_SRC&BIT (6) ) ) 
{
    if (SDIO- MMC_INT_SRC&BIT (0) ) 
    {
        SDIO- MMC_INT_SRC|=BIT (0) ; 
        if ( (SDIO- CMD_BUFF[4]&0x3F) ==cmd) 
        {
            指针符号 responR1= ( (SDIO- CMD_BUFF[3]  24) + (SDIO- CMD_BUFF[2]  16) + (SDIO- CMD_BUFF[1]  8) + (SDIO- CMD_BUFF[0]) ) ; 
            return SDIOCmdTrue; 
        }
    }
}
SDIO- MMC_INT_SRC|=BIT (6) ; 
return SDIOCmdError;     

}
uint8 SDIO_GetResponseR2 (uint8 指针符号 responR2buff)
{

uint8 i=0; 

for (i=0; i 200; i++) 
{
    while (!  (SDIO- MMC_INT_SRC&BIT (0) ) ) ; 
    SDIO- MMC_INT_SRC|=BIT (0) ; 
    printf ("ResponR2[135-128]=%d\n", SDIO- CMD_BUFF[15]) ; //R2 响应失败

    if (SDIO- CMD_BUFF[15]==0x3F) 
    {
        printf ("ResponR2[135-128]=%d\n", SDIO- CMD_BUFF[15]) ; 
        for (i=0; i 15; i++) 
            {
                指针符号 responR2buff++=SDIO- CMD_BUFF[i]; 
                printf ("CID[%d]=%d\n", i, SDIO- CMD_BUFF[i]) ; 
            }
            return SDIOCmdTrue; 
    }else
    {
        SD_SendCmd (CMD2, 0, MMC_IO_RradCidCsdRecp) ; 
    }
    
}
return SDIOCmdError; 

}

uint8 SDIO_GetResponseR3 (uint32 指针符号 responR3)
{

while (!  (SDIO- MMC_INT_SRC&BIT (6) ) ) 
{
    if (SDIO- MMC_INT_SRC&BIT (0) ) 
    {
        SDIO- MMC_INT_SRC|=BIT (0) ; 
        
        指针符号 responR3= ( (SDIO- CMD_BUFF[3]  24) + (SDIO- CMD_BUFF[2]  16) + (SDIO- CMD_BUFF[1]  8) + (SDIO- CMD_BUFF[0]) ) ; 
        return SDIOCmdTrue; 

    }
}
SDIO- MMC_INT_SRC|=BIT (6) ; 
return SDIOCmdError;     

}

uint8 Init_SDCard ()
{

uint8 respon, cnt=0; 
uint32 ReState; 
uint16 SD_RCA, SD_State; 
uint8 cid_csd_buff[16];     //获取 CID, CSD 缓存

Init_SDIO_IO () ; 
Init_SDIO_Reg () ; 
SDIO_LowSpeed () ; 

for (cnt=0; cnt 10; cnt++) // 74 个 CLK
{
    SDIO- MMC_IO=MMC_IO_JusCret8nck; 
    while (SDIO- MMC_IO&BIT (2) ) ; 
}

SD_SendCmd (CMD0, 0, MMC_IO_SendCmd6) ; //复位卡
WaiteCmdTransOver () ; 

查看更多

关注者
0
被浏览
1. 4k
1 个回答
isme
isme 认证专家 2022-11-07
冰镇大西瓜

可以看看这篇文章, 可能对你有帮助. http: //ask. winnermicro. com/article/36. html

撰写答案

请登录后再发布答案, 点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览