OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3996|回复: 3

STM32F411 1.8V 供电, 移植SD卡,初始化失败

[复制链接]

2

主题

6

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2016-8-29
在线时间
1 小时
发表于 2016-8-29 21:14:37 | 显示全部楼层 |阅读模式
1金钱
小弟自己做了一块开发板,使用STM32F411 作为主控,但是在移植  SD卡驱动和 USB通信的时候遇到了问题,希望大神可以帮助解答一下。

1. 小弟的板子使用 1.8V 供电,不知道 SD 卡 和 USB 能够支持1.8 V供电的MCU? 我在调试的时候 MCU 需要1.8V 供电SD卡才有 一些回应。1.8V 完全不能通讯。哪里需要设置吗?
   
2. 小弟的板子使用TF卡,在移植驱动的时候出现了问题
SD卡初始化失败。   卡在了 设置  4位宽度那里,  报错 SD_LOCK_UNLOCK_FAILED
麻烦大神帮忙找一下原因?



[mw_shl_code=c,true]//初始化SD卡
//返回值:错误代码;(0,无错误)
SD_Error SD_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        SD_Error errorstatus=SD_OK;         
        u8 clkdiv=0;
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, ENABLE);//SDIO复位

        GPIO_InitStructure.GPIO_Pin =SDIO_D0_PIN;         //PC8,9,10,11,12复用功能输出       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100M
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
        GPIO_Init(SDIO_D0_PORT, &GPIO_InitStructure);// PC8,9,10,11,12复用功能输出
       
        GPIO_InitStructure.GPIO_Pin =SDIO_D1_PIN;
        GPIO_Init(SDIO_D1_PORT, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin =SDIO_D2_PIN;
        GPIO_Init(SDIO_D2_PORT, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin =SDIO_D3_PIN;
        GPIO_Init(SDIO_D3_PORT, &GPIO_InitStructure);       

        GPIO_InitStructure.GPIO_Pin =SDIO_SCK_PIN;
        GPIO_Init(SDIO_SCK_PORT, &GPIO_InitStructure);       

        GPIO_InitStructure.GPIO_Pin =SDIO_CMD_PIN;
        GPIO_Init(SDIO_CMD_PORT, &GPIO_InitStructure);//PD2复用功能输出

        //引脚复用映射设置
        GPIO_PinAFConfig(SDIO_D0_PORT,SDIO_D0_SOURCE,SDIO_AF); //PC8,AF12
        GPIO_PinAFConfig(SDIO_D1_PORT,SDIO_D1_SOURCE,SDIO_AF);
        GPIO_PinAFConfig(SDIO_D2_PORT,SDIO_D2_SOURCE,SDIO_AF);
        GPIO_PinAFConfig(SDIO_D3_PORT,SDIO_D3_SOURCE,SDIO_AF);
        GPIO_PinAFConfig(SDIO_SCK_PORT,SDIO_SCK_SOURCE,SDIO_AF);       
        GPIO_PinAFConfig(SDIO_CMD_PORT,SDIO_CMD_SOURCE,SDIO_AF);       

        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SDIO, DISABLE);//SDIO结束复位

        //SDIO外设寄存器设置为默认值                           
        SDIO_Register_Deinit();

        NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器、

        errorstatus=SD_PowerON();                        //SD卡上电
        if(errorstatus==SD_OK)
    {
        errorstatus=SD_InitializeCards();                        //初始化SD?
    }
    else
    {
        SD_DEBUG(("1 failed.\r\n"));
    }   
   
        if(errorstatus==SD_OK)
    {
        errorstatus=SD_GetCardInfo(&SDCardInfo);        //获取卡信息
        }
    else
    {
        SD_DEBUG(("2 failed.\r\n"));
    }
       
    if(errorstatus==SD_OK)
        {
                errorstatus=SD_SelectDeselect((u32)(SDCardInfo.RCA<<16));//选中SD卡
    }
        else
        {
                SD_DEBUG(("3 failed.\r\n"));
        }
       
        if(errorstatus==SD_OK)
        {
                errorstatus=SD_EnableWideBusOperation(SDIO_BusWide_4b);        //4位宽度,如果是MMC卡,则不能用4位模式
        }
        else
        {
                SD_DEBUG(("4 failed.\r\n"));
        }
       
        if((errorstatus==SD_OK)||(SDIO_MULTIMEDIA_CARD==CardType))
        {                      
                if(SDCardInfo.CardType==SDIO_STD_CAPACITY_SD_CARD_V1_1||SDCardInfo.CardType==SDIO_STD_CAPACITY_SD_CARD_V2_0)
                {
                        clkdiv=SDIO_TRANSFER_CLK_DIV+2;        //V1.1/V2.0卡,设置最高48/4=12Mhz
                }
                else
                        clkdiv=SDIO_TRANSFER_CLK_DIV;        //SDHC等其他卡,设置最高48/2=24Mhz
                SDIO_Clock_Set(clkdiv);        //设置时钟频率,SDIO时钟计算公式:SDIO_CK时钟=SDIOCLK/[clkdiv+2];其中,SDIOCLK固定为48Mhz
                //errorstatus=SD_SetDeviceMode(SD_DMA_MODE);        //设置为DMA模式
                errorstatus=SD_SetDeviceMode(SD_POLLING_MODE);//设置为查询模式
                SD_DEBUG(("SD_SetDeviceMode ret : %x.\r\n", errorstatus));
        }
        else
        {
                SD_DEBUG(("5 failed.\r\n"));
        }
       
        if(errorstatus)
        {
                theECG.sd_status=0;
                theECG.sd_check_timeout = SD_CHECK_TIMEOUT/TICK_PERIOD_IN_MS;
                SD_DEBUG(("SD card initialization fail\r\n"));
        }
        else
        {
                theECG.sd_status=1;
                theECG.sd_check_timeout = 0;
                SD_DEBUG(("SD card initialization success\r\n"));
        }       
        return errorstatus;                 
}[/mw_shl_code]

[mw_shl_code=c,true]//设置SDIO总线宽度(MMC卡不支持4bit模式)
//wmode:位宽模式.0,1位数据宽度;1,4位数据宽度;2,8位数据宽度
//返回值:SD卡错误状态

//设置SDIO总线宽度(MMC卡不支持4bit模式)
//   @arg SDIO_BusWide_8b: 8-bit data transfer (Only for MMC)
//   @arg SDIO_BusWide_4b: 4-bit data transfer
//   @arg SDIO_BusWide_1b: 1-bit data transfer (默认)
//返回值:SD卡错误状态


SD_Error SD_EnableWideBusOperation(u32 WideMode)
{
        SD_Error errorstatus=SD_OK;
        if (SDIO_MULTIMEDIA_CARD == CardType)
        {
                errorstatus = SD_UNSUPPORTED_FEATURE;
                return(errorstatus);
        }       
        else if((SDIO_STD_CAPACITY_SD_CARD_V1_1==CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0==CardType)||(SDIO_HIGH_CAPACITY_SD_CARD==CardType))
        {
                if (SDIO_BusWide_8b == WideMode)   //2.0 sd不支持8bits
                {
                        errorstatus = SD_UNSUPPORTED_FEATURE;
                        return(errorstatus);
                }
                else   
                {
                        errorstatus=SDEnWideBus(WideMode);

                        SD_DEBUG(("SDEnWideBus: %d\r\n", errorstatus));
                       
                        if(SD_OK==errorstatus)
                        {
                                SDIO->CLKCR&=~(3<<11);                //清除之前的位宽设置   
                                SDIO->CLKCR|=WideMode;//1位/4位总线宽度
                                SDIO->CLKCR|=0<<14;                        //不开启硬件流控制
                        }
                }  
        }
        return errorstatus;
}[/mw_shl_code]

[mw_shl_code=c,true]//SDIO使能宽总线模式
//enx:0,不使能;1,使能;
//返回值:错误状态
SD_Error SDEnWideBus(u8 enx)
{
        SD_Error errorstatus = SD_OK;
        u32 scr[2]={0,0};
        u8 arg=0X00;
       
        if(enx)
        {
                arg=0X02;
        }
        else
        {
                arg=0X00;
        }
       
        if(SDIO->RESP1&SD_CARD_LOCKED)
        {
                SD_DEBUG(("SD CARD LOCKED.\r\n"));
                return SD_LOCK_UNLOCK_FAILED;//SD卡处于LOCKED状态       
        }
       
        errorstatus=FindSCR(RCA,scr);                                                //得到SCR寄存器数据
        if(errorstatus!=SD_OK)
        {       
                return errorstatus;
        }
       
        if((scr[1]&SD_WIDE_BUS_SUPPORT)!=SD_ALLZERO)                //支持宽总线
        {
                SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) RCA << 16;//发送CMD55+RCA,短响应       
                SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD;
                SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
                SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
                SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
                SDIO_SendCommand(&SDIO_CmdInitStructure);

                errorstatus=CmdResp1Error(SD_CMD_APP_CMD);
               
                 if(errorstatus!=SD_OK)
                {
                        return errorstatus;
                 }
               
                SDIO_CmdInitStructure.SDIO_Argument = arg;//发送ACMD6,短响应,参数:10,4位;00,1位.       
                SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_SD_SET_BUSWIDTH;
                SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
                SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
                SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
                SDIO_SendCommand(&SDIO_CmdInitStructure);

                errorstatus=CmdResp1Error(SD_CMD_APP_SD_SET_BUSWIDTH);

                return errorstatus;
        }
        else
        {
                return SD_REQUEST_NOT_APPLICABLE;                                //不支持宽总线设置          
        }
}        [/mw_shl_code]

  3.3 V供电情况下的输出


1.8V 供电情况下的输出




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2016-8-29
在线时间
1 小时
 楼主| 发表于 2016-8-29 21:17:00 | 显示全部楼层
1.8V 供电时候的串口打印
CMD0 RET: 0
CMD8 RET: 3
CMD55 RET: 3
CMD1 RET: 3
1 failed.
2 failed.
3 failed.
4 failed.
5 failed.
SD card initialization fail
Welcome to EGC Project...
..................................................................................................................
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2016-8-29
在线时间
1 小时
 楼主| 发表于 2016-8-29 21:18:20 | 显示全部楼层
3.3V 时候的串口输出
CMD0 RET: 0
CMD8 RET: 0
CMD55 RET: 0
SD CARD LOCKED.
SDEnWideBus: 14
5 failed.
SD card initialization fail
Welcome to EGC Project...
...
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2016-8-31 22:11:55 | 显示全部楼层
3.3V也出问题了。。。
慢慢查吧。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-28 06:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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